Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

503 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inspoter

Inspoter — self-hosted панель для управления доменами, DNS, серверами и хостингом, мониторинга доступности, работы с почтой и webhook, а также просмотра логов и оповещений. Данные разделены по рабочим пространствам, поэтому один экземпляр приложения подходит для нескольких команд или проектов.

Возможности

  • дашборды: именованные страницы с виджетами на сетке 12 колонок;
  • домены и DNS-записи из Cloudflare, Hetzner DNS и GoDaddy;
  • серверы Hetzner Cloud и хостинг Hostinger или cPanel;
  • HTTP-, TCP- и PING-мониторинг сервисов;
  • мониторинг метрик VPS: CPU, память, swap, load, диск и uptime через Docker-агент;
  • почтовые аккаунты IMAP/SMTP, сообщения и вложения;
  • каналы сообщений, входящие и исходящие webhook, совместимые с Discord;
  • закладки, логи и оповещения;
  • MCP-сервер и REST API управления разделом «Сообщения» для ИИ-ассистентов, с правами на уровне API-токена;
  • рабочие пространства, участники и переключение между командами;
  • интерфейс на английском и русском языках;
  • вход по паролю или через Authentik OIDC.

Стек и требования

  • Next.js 16.2.10, React 19 и TypeScript;
  • Tailwind CSS v4 и shadcn/ui;
  • Prisma 7 и PostgreSQL 16;
  • Vitest и Playwright;
  • Python 3.12 (Docker-агент сбора метрик, stdlib only);
  • Node.js 24.x и pnpm 11.12.0;
  • Docker с Docker Compose для приведённых ниже команд запуска PostgreSQL и всего приложения.

Версия pnpm закреплена в package.json. Для её установки через Corepack выполните corepack enable.

Запуск

Скопируйте контракт переменных окружения и заполните обязательные значения:

cp .env.example .env

Для входа по паролю задайте OPERATOR_USERNAME и одну из переменных: OPERATOR_PASSWORD_HASH или OPERATOR_PASSWORD. Вторая предназначена только для разработки. Параметры базы задаются через DATABASE_URL.

Нативный production-запуск

Следующие команды запускают PostgreSQL в Docker, а собранное приложение — напрямую в Node.js:

docker compose up -d db
pnpm install
pnpm db:migrate
pnpm db:seed
pnpm build
pnpm start

Приложение будет доступно по адресу http://localhost:3000.

Разработка

После установки зависимостей, настройки .env и применения миграций запустите dev-сервер с Turbopack:

pnpm dev

Приложение будет доступно по адресу http://localhost:3800.

Docker

Compose запускает PostgreSQL и production-сборку приложения. Хостовый порт 3800 направлен на порт 3000 контейнера:

docker compose up -d --build
docker compose exec app pnpm db:seed

Приложение будет доступно по адресу http://localhost:3800.

Текущий docker-compose.yml не передаёт сервису app переменные CREDENTIAL_ENCRYPTION_KEY и AUTHENTIK_*. Поэтому конфигурация провайдеров, почтовых аккаунтов, исходящих webhook и Authentik недоступна в этом режиме, пока эти переменные не будут явно добавлены в окружение сервиса. Вход по паролю продолжает работать.

Переменные окружения

Шаблон базовой конфигурации находится в .env.example. Основные переменные:

Переменная Требование Назначение
DATABASE_URL обязательна Подключение к PostgreSQL. Для БД из Compose при запуске приложения на хосте используется localhost:3832; внутри Compose — db:5432.
OPERATOR_USERNAME обязательна для базового seed Логин оператора, создаваемого командой pnpm db:seed.
OPERATOR_PASSWORD_HASH одна из двух Scrypt-хеш salt:hash; предпочтительный вариант.
OPERATOR_PASSWORD одна из двух Пароль в открытом виде только для разработки; игнорируется, если задан хеш.
CREDENTIAL_ENCRYPTION_KEY для защищённых учётных данных 64-символьный hex-ключ для шифрования данных провайдеров, почтовых аккаунтов и секретов исходящих webhook.
AUTHENTIK_ISSUER, AUTHENTIK_CLIENT_ID, AUTHENTIK_CLIENT_SECRET, AUTHENTIK_REDIRECT_URI необязательны, задаются вместе Включают вход через Authentik OIDC. Если группа не задана, доступен вход по паролю.
LIST_PAGE_SIZE необязательна Размер страницы; значение по умолчанию — 50.
WEBHOOK_RATE_LIMIT, WEBHOOK_RATE_WINDOW_MS, WEBHOOK_MAX_BODY_BYTES необязательны Ограничения для входящих webhook.
WEBHOOK_AUTO_DISABLE_AFTER необязательна Сколько неудачных доставок подряд отключают исходящий webhook (по умолчанию 10). Счётчик обнуляется успешной доставкой и ручным включением.
BACKUP_MAX_IMPORT_BYTES, BACKUP_IMPORT_TX_TIMEOUT_MS необязательны Резервное копирование (/settings/backup): максимальный размер импортируемого архива (по умолчанию 512 МиБ) и таймаут транзакции импорта (по умолчанию 5 минут).
SERVER_METRICS_RATE_LIMIT, SERVER_METRICS_RATE_WINDOW_MS необязательны Rate limiting для публичного метрик-эндпоинта: максимум запросов на пару «токен + IP-адрес источника» (по умолчанию 12) и окно в мс (по умолчанию 60 000).
LLM_REQUEST_TIMEOUT_MS, LLM_CALL_RATE_LIMIT, LLM_CALL_RATE_WINDOW_MS необязательны Модели ИИ: таймаут одного запроса к модели (по умолчанию 60 000 мс) и лимит вызовов на рабочее пространство (по умолчанию 60 вызовов в час). Адрес модели и ключ задаются в UI, а не здесь.

Дашборды и виджеты

Раздел «Дашборды» — обзорные страницы рабочего пространства. Дашбордов может быть сколько угодно, они общие для всех участников пространства, а один из них можно назначить стартовым: именно он открывается сразу после входа. Если стартовый не выбран, открывается первый по порядку.

Виджеты лежат на сетке из 12 колонок. Перетаскивание и изменение размера доступны только в режиме редактирования (кнопка «Редактировать»), поэтому в обычном режиме плитки остаются интерактивными. Размер меняется мышью за уголок в правом нижнем углу или стрелками с клавиатуры, когда уголок в фокусе. На экране уже 640 пикселей сетка превращается в одну колонку, а редактирование раскладки отключается.

Данные виджетов обновляются раз в минуту одним запросом на дашборд, пока вкладка активна. Ошибка одного виджета не ломает страницу: такая плитка показывает причину, а остальные продолжают работать.

Доступные виджеты:

Виджет Что показывает Настройки
Часы и дата Текущее время и дату Формат 12/24 ч, секунды, дата, временная зона
Погода Текущую погоду по координатам (Open-Meteo, без API-ключа) Название места, широта, долгота, °C/°F
Календарь Сетку месяца с отметками дней, когда были события Источники: оповещения, инциденты сервисов, письма, действия
Заметка Произвольный текст Текст заметки
Закладки Плитки ссылок из закладок Категория, количество
Статусы сервисов Сводку мониторинга и список сервисов Список сервисов, количество
Метрики серверов CPU, память и диск по данным агента Сервер, количество
Почта Последние письма Ящик, только непрочитанные, количество
Оповещения Последние оповещения Уровни важности, количество
Логи Последние записи журнала Уровни, количество

Виджет погоды — единственный виджет, обращающийся к внешнему сервису: серверный запрос к api.open-meteo.com с координатами из настроек виджета, ответ кешируется в памяти процесса на 10 минут. Если такой запрос нежелателен, не добавляйте этот виджет — остальные работают только на данных самого приложения. Второй и последний внешний адресат приложения — эндпоинт модели из раздела «Модели ИИ (LLM)», и он тоже включается только вручную.

Дашборды входят в резервную копию рабочего пространства как отдельный раздел «Дашборды». Признак стартового дашборда при импорте не переносится: он уникален в пределах пространства, поэтому после восстановления назначьте стартовый заново.

Провайдеры

Провайдеры подключаются в разделе Настройки → Провайдеры (/settings/providers). Токены и ключи API хранятся в базе в зашифрованном виде для текущего рабочего пространства; отдельные env-переменные для токенов провайдеров не используются. Добавлять, изменять и удалять провайдеров может любой участник рабочего пространства — ограничения по роли (OWNER/MEMBER) здесь нет.

Раздел Провайдеры
Домены и DNS Cloudflare, Hetzner DNS, GoDaddy
Серверы Hetzner Cloud
Хостинг Hostinger, cPanel WHM, cPanel UAPI
LLM любой endpoint, совместимый с OpenAI API

Без настроенного провайдера соответствующий раздел показывает пустое состояние.

Модели ИИ (LLM)

Приложение умеет обращаться к языковой модели через любой endpoint, совместимый с OpenAI API: локальные Ollama, vLLM, LM Studio, а также облачные OpenRouter и OpenAI. Пока это только инфраструктура — пользовательских AI-функций в интерфейсе ещё нет.

Модель подключается там же, где остальные провайдеры: Настройки → Провайдеры, тип OpenAI-compatible. Нужны три поля — базовый URL API (например http://127.0.0.1:11434/v1 для Ollama), имя модели и API-ключ. Ключ, как и другие учётные данные, хранится в базе в зашифрованном виде для текущего рабочего пространства; наружу отдаётся только маскированный хвост. Отдельной env-переменной для ключа нет.

Пока учётные данные не заданы, слой моделей полностью выключен: ни одного исходящего запроса не выполняется и ошибок не возникает.

Что стоит знать до подключения:

  • Куда уходят данные. Это второй и последний внешний адресат приложения (первый — Open-Meteo в виджете погоды) и единственный, в тело запроса которого попадает содержимое рабочего пространства. Рекомендуемый режим — локальная модель: при базовом URL вида http://127.0.0.1:11434/v1 данные не покидают хост. Облачный провайдер поддерживается наравне с локальным, но выбор делаете вы, задавая URL.
  • Учёт. Каждый вызов модели попадает в журнал действий: модель, режим драйвера и число израсходованных токенов, а для неудачных вызовов — категория ошибки.
  • Лимит. На рабочее пространство действует ограничение LLM_CALL_RATE_LIMIT вызовов за LLM_CALL_RATE_WINDOW_MS (по умолчанию 60 в час).
  • Таймаут. Один запрос к модели ждёт ответа не дольше LLM_REQUEST_TIMEOUT_MS (по умолчанию 60 секунд) и не повторяется автоматически: повтор стоил бы вторых токенов, а модель к этому моменту обычно всё ещё генерирует ответ.

Документация публичных webhook

Swagger UI доступен авторизованным пользователям в разделе Настройки → API документация (/settings/api-docs; для русской локали — /ru/settings/api-docs). Приложение передаёт проверенную в репозитории спецификацию странице на сервере и не публикует отдельный /openapi.json.

Контракт OpenAPI 3.1.1 описывает публичные маршруты, не использующие сессионную куку:

  • POST /api/webhooks/{type} с Bearer-токеном;
  • POST /api/webhooks/channels/{webhookId}/{token} с секретным токеном в URL;
  • POST и GET /api/discord/webhooks/{webhookId}/{token} — Discord-совместимый приём, секрет в URL;
  • POST /api/discord/webhooks/{webhookId}/{token}/slack — форма Slack;
  • POST /api/server-metrics с Bearer-токеном;
  • POST /api/mcp с Bearer-токеном.

Поле category в payload типа alert необязательно: отправитель без понятия категорий (Alertmanager, Zabbix, UptimeRobot) получает 201, а оповещение попадает в раздел без категории — оператор проставляет её в таблице. Имя категории сопоставляется без учёта регистра, поэтому availability и Availability от разных систем попадают в одну категорию. У подписчиков исходящих webhook это значит, что поле category в событии ALERT_CREATED может быть null.

Все они определяют рабочее пространство по API-токену и не используют X-Inspoter-Workspace. Описания операций и примеры в Swagger UI написаны на английском. Внутренние dashboard API, OIDC и маршруты управления токенами не входят в публичную спецификацию. Не сохраняйте и не передавайте channel webhook URL через логи: URL содержит секрет.

Проверить спецификацию можно так:

node scripts/check-public-openapi.mjs

Скрипт фиксирует список публичных путей, проверяет, что каждый объявленный маршрут действительно экспортирует POST, и отклоняет workspace-заголовки, внешние URL серверов и секреты в примерах. Пооперационные утверждения — включая лимиты Discord-payload и rate-limit-заголовки — живут в tests/unit/openapi/public-openapi.test.ts и выполняются вместе с pnpm test:unit.

Совместимость с Discord

Вебхуки Inspoter говорят на проводном формате Discord в обе стороны. Нормативный контракт — specs/discord-webhook-compatibility.md; ниже только то, что нужно оператору.

Приём: Discord → Inspoter

Канальный вебхук создаётся в настройках канала (значок шестерёнки → «Вебхуки»). Диалог показывает три значения, построенных из одного секрета: обычный URL, готовый cURL и Discord-совместимый URL. Любая интеграция, умеющая писать в Discord-канал — CI, Grafana, Sentry, Uptime Kuma, GitHub Actions — начинает писать в Inspoter подстановкой этого адреса вместо ссылки на discord.com. Тело запроса переписывать не нужно.

curl -X POST 'http://your-host/api/discord/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN?wait=true' \\
  -H 'Content-Type: application/json' \\
  -d '{"username":"CI","content":"Build 842 passed","embeds":[{"title":"Build 842","color":3066993}]}'

Поддерживаются content (≤2000), embeds (≤10 карточек, ≤6000 символов суммарно), username, avatar_url, tts, flags, application/json и multipart/form-data с payload_json. Ответ по умолчанию — 204 без тела; ?wait=true даёт 200 и объект сообщения. Ошибки приходят в форме Discord (50006, 50035, 40005, 401, 429 с retry_after). Embeds отображаются в канале карточками.

Discord-URL — такой же секрет, как обычный: обратный прокси обязан вырезать путь /api/discord/webhooks/* из логов.

Отправка: Inspoter → Discord

У каждого исходящего вебхука в Настройках → Исходящих вебхуках есть формат доставки:

Формат Что уходит на провод
INSPOT (по умолчанию) Собственный конверт с подписью HMAC-SHA256 в X-Inspot-Signature. Существующие подписки не меняются.
DISCORD_EXECUTE Тело Discord Execute Webhook: событие уходит карточкой embed. Указывайте URL вебхука Discord-канала.
DISCORD_EVENTS Конверт Discord Webhook Events с подписью Ed25519, PING при создании, таймаут 3 с. Публичный ключ виден в UI.

DISCORD_EXECUTE уважает retry_after из ответа 429. После WEBHOOK_AUTO_DISABLE_AFTER неудачных доставок подряд вебхук отключается автоматически, а ручное включение обнуляет счётчик.

MCP (Model Context Protocol)

POST /api/mcp — эндпоинт Model Context Protocol: ИИ-ассистент (Claude Code и Claude Desktop, Cursor, VS Code) получает доступ к почте, оповещениям, закладкам, сообщениям, серверам, сервисам и логам рабочего пространства. Транспорт — Streamable HTTP без сессий; авторизация — тот же универсальный API-токен, что и у webhook, через заголовок Authorization: Bearer <токен>.

Выдача токена

Настройки → API-токены (/settings/webhooks). При создании токена отметьте нужные права; секрет показывается один раз. Права можно изменить позже кнопкой «Права» — секрет при этом не меняется, а ротация токена права сохраняет.

Токен без единого права остаётся токеном приёма webhook и метрик: на /api/mcp он получает 401. Поэтому все токены, выданные до появления MCP, доступа к данным рабочего пространства не получают.

Подключение клиента

{
  "mcpServers": {
    "inspoter": {
      "type": "http",
      "url": "https://dashboard.example.com/api/mcp",
      "headers": { "Authorization": "Bearer ВАШ_ТОКЕН" }
    }
  }
}

Клиентам без поддержки HTTP-транспорта подойдёт обёртка mcp-remote: npx mcp-remote https://dashboard.example.com/api/mcp --header "Authorization: Bearer ВАШ_ТОКЕН".

Инструменты и права

tools/list показывает только те инструменты, на которые у токена есть права.

Право Инструменты
mail:read mail_accounts_list, mail_folders_list, mail_labels_list, mail_search, mail_get
mail:write mail_draft_save, mail_send
alerts:read alerts_search, alerts_get, alert_categories_list
alerts:write alerts_set_category, alert_category_create
bookmarks:read bookmarks_search, bookmarks_get, bookmark_categories_list
bookmarks:write bookmark_create
messages:read message_categories_list, messages_list, channel_webhooks_list
messages:write message_category_create, message_category_rename, message_channel_create, message_channel_rename, message_send, channel_webhook_create, channel_webhook_revoke
servers:read servers_list, server_get
services:read services_list, service_get, service_checks
logs:read logs_search

Категоризация оповещений: alerts_search с categoryId: "none" возвращает оповещения без категории, alert_category_create заводит категорию (существующая по такому же имени переиспользуется), alerts_set_category привязывает оповещение к категории или снимает привязку при categoryId: null. Проставленная так категория помечается в интерфейсе как «Поставлено моделью», и оператор может её изменить.

Черновики и отправка работают с любого IMAP-аккаунта рабочего пространства: mail_accounts_list возвращает доступные аккаунты, их id передаётся в mail_draft_save и mail_send. Системный аккаунт WEBHOOK только принимает почту и отправлять через него нельзя.

Показатели серверов (CPU, load, память, swap, диск, uptime) приходят прямо в ответе servers_list и server_get в поле metrics; история проверок сервисов — в service_checks.

Раздел «Сообщения»: message_categories_list возвращает дерево категорий с каналами, message_category_create и message_channel_create работают по принципу get-or-create (совпадение имени без учёта регистра, поэтому повторный запуск того же сценария ничего не дублирует), message_send пишет в канал. Удаления категорий и каналов у агента нет — оно уносит всю переписку и остаётся действием оператора в интерфейсе. Право messages:write включает и управление вебхуками канала: channel_webhook_create возвращает URL с секретом один раз, channel_webhook_revoke его отзывает.

Rate limit общий с webhook-эндпоинтами и настраивается через WEBHOOK_RATE_LIMIT и WEBHOOK_RATE_WINDOW_MS. GET и DELETE на /api/mcp отвечают 405: сессии протокола не поддерживаются.

API управления разделом «Сообщения»

/api/v1/messages/** — то же самое, что даёт MCP, но обычным REST: для клиентов и скриптов без поддержки MCP. Авторизация — тот же bearer-токен и те же права messages:read / messages:write; рабочее пространство берётся из токена, сессионная cookie и заголовок X-Inspoter-Workspace не участвуют. Полная схема — в Настройки → Документация API (/settings/api-docs).

Метод и путь Право Действие
GET /api/v1/messages/categories messages:read категории с каналами
POST /api/v1/messages/categories messages:write get-or-create категории: 201 — создана, 200 — уже была
PATCH /api/v1/messages/categories/{categoryId} messages:write переименование категории
POST /api/v1/messages/channels messages:write get-or-create канала в категории
PATCH /api/v1/messages/channels/{channelId} messages:write переименование канала
GET /api/v1/messages/channels/{channelId}/messages messages:read лента канала с курсорной пагинацией
POST /api/v1/messages/channels/{channelId}/messages messages:write отправка сообщения
GET /api/v1/messages/channels/{channelId}/webhooks messages:read вебхуки канала без секретов
POST /api/v1/messages/channels/{channelId}/webhooks messages:write новый вебхук канала; URL с секретом отдаётся один раз
DELETE /api/v1/messages/channels/{channelId}/webhooks/{webhookId} messages:write отзыв вебхука
curl -X POST https://dashboard.example.com/api/v1/messages/categories \
  -H "Authorization: Bearer ВАШ_ТОКЕН" -H "Content-Type: application/json" \
  -d '{"name":"Deployments"}'

curl -X POST https://dashboard.example.com/api/v1/messages/channels \
  -H "Authorization: Bearer ВАШ_ТОКЕН" -H "Content-Type: application/json" \
  -d '{"categoryId":"<id категории>","name":"releases"}'

curl -X POST https://dashboard.example.com/api/v1/messages/channels/<id канала>/messages \
  -H "Authorization: Bearer ВАШ_ТОКЕН" -H "Content-Type: application/json" \
  -d '{"content":"Деплой завершён на web-01."}'

Ошибки приходят в виде { "error": { "code", "message" } }: 401 — токена нет либо он отозван, канальный или без прав MCP; 403 — не хватает нужного права; 404 — объекта нет в рабочем пространстве токена; 400 (VALIDATION_FAILED) — тело не прошло проверку, поле issues указывает на конкретное поле; 429 — превышен общий с webhook rate limit.

Сообщения, отправленные по токену (и через REST, и через MCP), сохраняются с признаком AGENT и в ленте помечаются как «Агент»; автором становится имя токена, если явный author не передан. Изменения, сделанные REST-маршрутами, попадают в журнал действий под именем токена — MCP-инструменты в журнал не пишут, как и остальные существующие инструменты.

Метрики серверов (VPS Metrics Agent)

Dockerized Python-агент собирает OS-метрики (CPU, память, swap, load average, диск, uptime) с хоста и отправляет их в dashboard каждые 60 секунд по HTTPS.

Быстрый старт

  1. Создайте API-токен в разделе Настройки → API-токены (или используйте существующий): один workspace-токен принимает и входящие webhook, и метрики. Одноразовый секрет показывается при создании; доступна ротация.
  2. На карточке сервера в разделе Серверы откройте диалог подключения агента и скопируйте установочный сниппет.
  3. Подставьте токен в .env агента и выполните сниппет на целевом сервере.

Определение сервера

Токен не привязан к конкретному серверу. Dashboard определяет сервер на каждой отправке метрик по заявленным глобальным IPv4-адресам: сначала по уже существующим claims адресов, затем — через инвентарь провайдера, а если совпадений нет — создаёт agent-only запись сервера (для хостов без глобального IPv4 запись переиспользуется по hostname). При неоднозначном совпадении запрос отклоняется с 409 SERVER_MATCH_AMBIGUOUS.

Состояния метрик

Состояние Значение
not_configured Данных от агента ещё нет
live Свежий снимок (менее 180 секунд)
stale Последний снимок старше 180 секунд

stale означает «снапшоты не доходят», а не «сервер недоступен» — состояние питания показывает отдельный индикатор. Агент пишет в лог только класс статуса (2xx/4xx/5xx), поэтому причину отказа выясняют повтором запроса через curl с того же хоста: см. таблицу симптомов в metrics-agent/README.md. Частый случай — WAF перед dashboard, блокирующий агента по User-Agent.

Ёмкость и использование — разные источники

Блок характеристик карточки (CPU, RAM, Диск, ОС) приходит из инвентаря провайдера, блок метрик — от агента. Диск провайдера берётся из primary_disk_size, то есть из фактического диска виртуальной машины: номинал тарифа (server_type.disk в Hetzner API) расходится с ним навсегда после апгрейда в режиме «CPU и RAM только». Строка Диск (использование) всегда описывает корневую ФС и совпадает с df -h / на хосте.

Docker Compose агента

Шаблон metrics-agent/compose.yml монтирует /proc и probe-директорию хоста:

# На целевом сервере:
install -d -m 0555 /var/lib/inspoter-metrics-agent/rootfs-probe
# Задайте METRICS_ENDPOINT, METRICS_TOKEN, SERVER_IPS в .env
docker compose -f metrics-agent/compose.yml up -d

Образ Python 3.12-slim, non-root, read-only filesystem, cap_drop: ALL. Зависимости pip не требуются.

Публичный API

POST /api/server-metrics — единственный публичный эндпоинт для приёма метрик. Авторизация через универсальный API-токен рабочего пространства (Bearer, SHA-256 hash-only) — тот же токен, что и для входящих webhook. Сессионная аутентификация не используется. Rate limit: 12 запросов в минуту на пару «токен + IP» (настраивается через env). Успешный ответ содержит { code, localServerId }.

Управление токенами: GET/POST /api/webhook-tokens, PATCH/DELETE /api/webhook-tokens/[id], POST /api/webhook-tokens/[id]/rotate — защищены сессионной аутентификацией и доступны любому участнику рабочего пространства. PATCH меняет права MCP (см. раздел выше).

Демо-данные

После базового seed можно добавить демонстрационные закладки, логи, оповещения, почтовые сообщения, каналы сообщений и токен входящего webhook:

pnpm db:seed:demo

Demo seed не создаёт домены, серверы, записи хостинга или сервисы мониторинга. Эти разделы заполняются через подключённые провайдеры или интерфейс приложения.

Разработка и тесты

pnpm dev              # dev-сервер, http://localhost:3800
pnpm lint             # ESLint и проверка нативных контролов
pnpm typecheck        # TypeScript без генерации файлов
pnpm format           # форматирование Prettier
pnpm format:check     # проверка форматирования Prettier
pnpm openapi:check    # lint и проверка публичного OpenAPI-контракта

pnpm test             # все Vitest-тесты (unit + integration)
pnpm test:unit        # чистые unit-тесты — без БД, без Docker
pnpm test:integration # интеграционные тесты с БД (нужен test Postgres на 3833)
pnpm test:e2e         # e2e-тесты (Playwright)
pnpm test:ci          # полный CI-профиль

E2E- и CI-тесты используют отдельную базу из docker-compose.test.yml. Её переменные описаны в .env.test.example.

About

Inspoter is a self-hosted dashboard for domains, DNS, servers, hosting, uptime monitoring, mail, webhooks, logs, alerts, and team workspaces.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages