Ведар — туристическая ОС Камчатки
Платформа полного цикла — от поиска маршрута до экстренной помощи в поле. Ранее известна как TourHab / KamchatourHub / Volcano OS.
vedarai.ru · Next.js 15 · PostgreSQL · TypeScript strict · PWA · Offline-first · AI
Что это
B2C/B2B платформа: туристы ищут маршруты и бронируют туры, операторы управляют предложениями, гиды ведут группы, партнёры сдают жильё и снаряжение. В основе — безопасность: каждое место имеет профиль опасности, реалтайм-статус и привязку к МЧС.
Работает в поле без интернета: офлайн-карты, экстренная страница, инструкции выживания, офлайн-очередь SOS (уходит сам при появлении связи) и QR-эстафета — попутчик сканирует сигнал без сети у обоих, его телефон доставляет SOS из зоны покрытия. Меш-ретрансляция — дополнительный канал, когда у соседа по группе связь осталась. Экстренный ответ не зависит от AI: детерминированный SOS-детектор добавляет телефоны 112/МЧС к ответу любого чата платформы, даже когда AI-конвейер лежит целиком.
MCP-сервер для ИИ-агентов
У Ведара есть публичный MCP-сервер (vedar-mcp): endpoint https://vedarai.ru/api/mcp, транспорт Streamable HTTP (JSON-RPC 2.0), авторизация не требуется. 13 инструментов: туры и их реальная занятость, безопасность мест и маршрутов, погода, жильё, трансферы, план поездки, заявки с подтверждением человеком. Подробнее: vedarai.ru/mcp · манифест /.well-known/mcp.json · /llms.txt.
В каталогах: официальный реестр MCP — ru.vedarai/mcp (манифест публикации — server.json), Smithery — tourhabk/vedar (npx -y smithery mcp add tourhabk/vedar), Glama — glama.json. Идентификаторы — в lib/mcp/catalogs.ts; их же отдают манифест, /llms.txt и /mcp.
Vedar — Kamchatka travel (English). Public MCP server for AI agents: live tours and availability, safety alerts, places, weather, stays, trip plans. Endpoint https://vedarai.ru/api/mcp, Streamable HTTP, no auth.
Стек
| Слой | Технология |
|---|---|
| Frontend | Next.js 15 App Router, TypeScript strict, Tailwind CSS |
| База данных | PostgreSQL — прямой SQL, без ORM |
| Аутентификация | JWT, role-based middleware |
| AI | Waterfall: 14 провайдеров — OpenRouter · DeepSeek · Gemini · MiMo · GLM · NVIDIA · Groq · Cerebras · Mistral · xAI · YandexGPT · MiniMax · MuseSpark · Anthropic. Плюс Mistral OCR (паспорта маршрутов) |
| PWA | Service Worker, Web Push (VAPID), Background Sync, IndexedDB |
| Меш | WebRTC P2P (VolcanoMesh) — SOS-ретрансляция между устройствами группы |
| Деплой | Timeweb Cloud — автодеплой при пуше в main |
| Боты | Telegram + MAX (Kuzmich) |
Масштаб
Код — цифры обновляет node scripts/update-readme-stats.mjs; запускает его post-merge.yml после каждого мержа (из CI проверка снята 15.08: устаревшая витрина держала выкладку прода):
| Метрика | Значение |
|---|---|
| Страниц | 215 |
| API routes | 788 |
| UI компонентов | 184 |
| lib-модулей | 742 |
| SQL миграций | 547 (последняя 1029) |
| Юнит-тестов | 13624 в 1279 файлах |
| GitHub Actions | 152 workflow |
Каталог — перепись GET /api/cron/catalog-census на проде, замер 2026-09-26 (обновляется после каждого мержа; «живые» — видимые и не слитые):
| Сущность | Живых |
|---|---|
Мест (places) | 378 |
Маршрутов (kamchatka_routes) | 389 |
| Гидов с действующей аттестацией | 112 |
places: is_visible = true и merged_into_id IS NULL · kamchatka_routes: is_visible = true и merged_into_id IS NULL · guide_certifications: различных guide_id с is_verified = true и неистёкшим expiry_date
Структура данных
Три сущности — три таблицы:
places — географический факт: вулкан, озеро, источник
kamchatka_routes — маршрут между точками, трек, сложность
operator_tours — коммерческий продукт: цена, слоты, бронь
Безопасность каждого места — location_safety_profile + location_real_time_status.
Связь маршрут→точки — route_waypoints.
Офлайн и безопасность в поле
SOS-страховщик поверх всех чатов
lib/safety/sos-detector.ts— детерминированный детектор ЧП (8 категорий: заблудился, травма, медведь, лёд, лавина, группа не вернулась, замерзание, бедствие)- При признаках беды к ответу ЛЮБОГО чата (веб, стрим на главной, Telegram/MAX, планировщик) добавляются 112, МЧС и совет по ситуации — независимо от модели
/emergency.html — статичная аварийная страница
- 34 КБ (замер 04.09), нулевые зависимости, OLED-тёмная тема, кэшируется при установке PWA
- GPS-координаты → скопировать → назвать оператору 112
- 4 протокола inline: Потерялся · Медведь · Травма · Холодно
/sos — расширенный SOS-экран
- Отправка сигнала с офлайн-очередью (IndexedDB + Background Sync)
- VolcanoMesh: WebRTC P2P ретрансляция SOS через группу
- Спутниковая диктовка — текст для чтения оператору
/safety/offline — инструкции выживания
- Медведь, вулкан, гипотермия, потерялся, сигнализация, вода — precached
Офлайн-карта
- Тайлы Камчатки зум 7–9 кэшируются при установке (~8 МБ)
- Зум 10+ скачивается по маршруту через
/offline/manage
AI-агенты
| Группа | Примеры | Расписание |
|---|---|---|
| Безопасность | Safety Ingest, Watchdog, Rescue, SOS Bridge, KVERT ACC | каждые 5 мин – 6 ч |
| Контент | Editor, Import Routes, Enrich Routes, Places Enricher | 22:00–23:00 UTC |
| Разведка | Scout Digest, Scout Innovator, Intelligence, KB Gap, Industry Intel, Legislation Sync | 07:00–08:00 UTC |
| Память | Memory Reflector, Contradiction Scanner (safety) | раз в сутки |
| Качество | Kuzmich Eval (faithfulness: фикстура + живые вопросы туристов), метрика заземления, SSR-сторож | еженедельно |
| Бизнес | Abandoned Bookings, Payouts, Tour Reminder, Leads | почасово / 06:00 UTC |
| Боты | Kuzmich (Telegram, MAX, Web, Widget) | realtime |
Loop-агенты (работают с репозиторием, loop engineering):
| Петля | Триггер | Что делает |
|---|---|---|
| CI Sweeper | CI упал | Читает лог, чинит: PR-ветка → фикс-коммит; main → hotfix draft-PR |
| Issue Triage | ежедневно 21:00 UTC | Размечает тикеты; safety/деньги → владельцу, тривиальные → draft-PR за ночь |
| Post-Merge Cleanup | мерж PR | Удаляет смерженные ветки, закрывает issue |
| Weekly Chronicle | вс 20:00 UTC | Хроника недели в .claude/MEMORY.md — межсессионная память агентов |
Уровень автономии L2: LLM-петли готовят draft-PR, мержит человек. Деньги и safety петли не решают — приносят владельцу с лейблом needs-owner.
Общая память агентов: каждый агент на старте читает readAgentBriefing() — состояние платформы, историю запусков, must-have контекст туризма на Камчатке.
Реестры: AGENTS.md · docs/AGENTS_BOOK.md
Хабы
| Хаб | Путь | Роли |
|---|---|---|
| Туристы | /hub/tourist/ | tourist |
| Операторы | /hub/operator/ | operator |
| Гиды | /hub/guide/ | guide |
| Агенты | /hub/agent/ | agent |
| Жильё | /hub/stay/ | stay-партнёр |
| Прокат снаряжения | /hub/gear/ | gear-партнёр |
| Безопасность | /hub/safety | public |
| Трансфер | /hub/transfer/ | transfer_operator |
| Рыбалка | /hub/fishing/ | public |
| Админ | /hub/admin/ | admin |
Разработка
Новому разработчику — docs/DEVELOPER_GUIDE.md: быстрый старт
(миграции с нуля не проигрываются — baseline + хвост), карта репозитория, две дороги туриста по коду,
неочевидные механизмы (офлайн-очередь SOS, три планировщика кронов, маркеры), отладка прода.
Схема базы — docs/DB_SCHEMA.md, снимается с настоящего PostgreSQL.
npm install
cp .env.example .env.local
npm run dev
npm run dev # dev-сервер
npx tsc --noEmit # type check (0 ошибок)
npx vitest run # тесты
npm run migrate # миграции локально
git push origin main # → Timeweb автодеплой
Ключевые соглашения
import { pool } from '@/lib/db-pool'— только named importFROM operator_bookings/FROM operator_tours— неbookings, неtours- SQL — только параметризованный (
$1, $2), никогда конкатенация - Все API routes — Zod-валидация входных данных
- Цвета — только CSS custom properties (
var(--accent),var(--ocean)) - AI — только через
callAIWaterfall()/callAIFast() - Критичные факты (безопасность, цены, телефоны, наличие мест) — только из инструментов/БД, самоотчетам модели не верить
SELECT * FROM kamchatka_routes— только черезv_kamchatka_routes_api
Полные правила: CLAUDE.md
Деплой
Push в main → Timeweb видит пуш → собирает Docker → start.js накатывает миграции → поднимает сервер.
Приложение: Fair Polydeuces на Timeweb Cloud. Репо: tourhabk-ui/pos.
Docker: standalone bundle ≤ 50 МБ, images.unoptimized: true (убирает sharp ~33 МБ).
Последние изменения (июль 2026)
- Разрешения ООПТ в данных — Кроноцкий заповедник в справочнике
parks(заявка + email), паркам сети «Вулканы Камчатки» проставлены официальные каналы оформления; карточка парка показывает только подтверждённые ссылки - Stay-ремонт по аудиту — гонка овербукинга закрыта транзакцией с advisory-lock, письма гостю честные («заявка принята», не «подтверждено»), платёжный URL от текущего запроса, поиск жилья по датам той же семантикой занятости, что и бронь
- Gear-ремонт по аудиту — единый прайсинг-модуль (сервер == форма), публичная воронка аренды с честными 409 по датам, уведомления партнёру, watchdog сторожит зависшие заявки
- Админ-аналитика ожила — три графика из реальных агрегатов, контракт страницы и API охраняется тестом-парсером, нет метрик — честная карточка ошибки вместо нулей
- Ребрендинг в Ведар — платформа живёт на vedarai.ru; SEO-канал переведён на SSR: листинги
/routes,/operators,/catalogрендерятся сервером с ItemList JSON-LD - SOS-страховщик — детерминированный детектор ЧП поверх всех чатов: телефоны 112/МЧС приходят даже при мёртвом AI-конвейере; телефон МЧС сверен с каноном платформы
- Честность AI измеряется — faithfulness-регрессия Кузьмича на живых вопросах туристов (модели различают тестовый и живой контекст), метрика заземления «конкретика без инструментов = флаг», карточки на
/hub/admin/health - Loop engineering — четыре петли работают с репозиторием: CI чинит себя, тикеты размечаются ночью, смерженные ветки убираются, хроника недели пишется в память агентов
- KVERT ACC вулканов — авиационные цветовые коды синкаются каждые 6 часов: бейдж на карточке вулкана + safety-контекст Кузьмича
- Кузьмич знает всю платформу — search_accommodations, search_gear, search_transfers (9 инструментов)
- МЧС-помощник туриста — самостоятельная регистрация группы: copy-friendly данные + deep-link на forms.mchs.gov.ru
Камчатка. Вулканы. Медведи. Код.