Greenfield-разработка платежей и ваучеров для круизного оператора

Крупный оператор речных круизов (анонимно) Туризм и пассажирские перевозки 2025 — 2026
6 839
туров «Прогулочного флота» в сезон
~3 сек
генерация PDF
15 мин
TTL на бронь

Услуги

  • complex-systems
  • legacy-modernization

Стек

  • SvelteKit 2
  • Svelte 5
  • Supabase Postgres
  • Hatchet
  • Gotenberg
  • PDFKit
  • Tailwind 4
  • shadcn-svelte

Тот же оператор речных круизов, второй продукт — «Прогулочный флот» (короткие прогулки на теплоходах 1-3 часа vs многодневные круизы основного «Круизного флота»). Задача: отдельный быстрый чекаут (бронирование+оплата за 2-3 экрана), общая backend-инфраструктура, без блокировки админ-фич основного продукта. Production-релиз 0.6.86 на pf.sputnik-germes.ru.

Контекст

У оператора уже работала legacy PHP-система бронирования прогулок — устаревший UX, проблемы с мобильной версией, тяжёлый чекаут на 5+ экранов. Параллельно велась миграция основного продукта (Круизного флота) на новый стек SvelteKit + Supabase.

Решение: отдельный фронтенд-проект frontend_mf (micro-frontend) на том же стеке, что и Круизный флот, со 100% переиспользованием backend (та же БД, те же RPC, те же shared-модули). Уникален только UI-слой Прогулочного флота, всё общее подключается через $shared alias.

Дополнительная сложность: legacy PHP-система продолжает работать (управление флотом, отчётность, выгрузки в 1С). Новый фронт должен делать атомарное создание заявок в legacy с TTL 15 минут до подтверждения оплаты.

Подход

  1. frontend_mf как micro-frontend. Уникальный код только специфики Прогулочного флота (короткий чекаут, прогулочные туры). Всё общее (UI-компоненты, утилиты, типы) — через $shared alias из Круизного флота. Принцип: «Круизный флот = primary, Прогулочный флот = derived через $shared/$frontendRoutes».
  2. Legacy bridge через mTLS + HMAC. Endpoint на 192.168.11.11:443/api/pf/create_booking: client cert pf-test/pf-prod от собственного CA + HMAC-SHA256(secret, ts.nonce.body), Idempotency-Key UUIDv4. Новый фронт «Прогулочного флота» делает атомарное создание заявки в legacy (aa_schet + aa_order[] + aa_place[]) со status=2 и TTL 15 минут до подтверждения оплаты.
  3. birthday обязателен в payload — нужен legacy для UPSERT aa_kontragent по fio + birthday. Без него legacy создаёт дубли контрагентов.
  4. Excursion PDF через Hatchet workflow. На сохранение версии экскурсии в админке → background рендер расписания PDF через excursion-schedule-generate workflow + Gotenberg → URL в /pdf/e/{slug}. Время генерации ≈ 3 секунды end-to-end.
  5. Universal Document Platform обслуживает оба продукта через единый pdf-tasks-worker (контейнер из hermes-stack) + общие таблицы voucher_jobs/voucher_templates. 9 LIVE PDF-шаблонов: 1 voucher Круизного флота + 1 voucher Прогулочного флота + 7 версий pf_excursion.
  6. Платежи через shared-pay. Альфа-банк СБП C2B + ЮKassa — переиспользованы из Круизного флота. Callback-обработка через выделенный pay-service для атомарности.

Результат

  • 6 839 прогулочных туров в promenade_tours за сезон 2026.
  • 7 версий pf_excursion (живущие документы, обновляются на старте сезона).
  • 15 минут TTL на бронь до оплаты — после автоматический rollback в legacy.
  • End-to-end за ~3 секунды: запрос → PDF в Supabase Storage → public URL → email клиенту.
  • Live E2E с реальной оплатой: заявка создана, ваучер отправлен через 3 секунды, бронь подтверждена.
  • Нулевой дублирующий код: 80% всего frontend Прогулочного флота — это $shared из Круизного флота. Любая правка в основном продукте сразу попадает во второй (если не помечено как специфика).

Что использовали

SvelteKit 2 + Svelte 5 runes + Tailwind 4 + shadcn-svelte (frontend_mf), Supabase Postgres 17 + RLS + Edge Functions Deno (backend), Hatchet TS SDK v1 (workflow engine), Gotenberg 8 (HTML→PDF), PDFKit (legacy backup для voucher), shared-pay + shared-notifications (общие модули из Круизного флота), mTLS + HMAC + Idempotency (legacy bridge), Альфа-банк СБП C2B + ЮKassa (платежи), Caddy auto-TLS, systemd, Docker Compose. AI-усиление: Claude Code SDK + Hermes Stack (9 docker-сервисов). Frontend через $shared alias переиспользует ~80% Круизного флота.

Похожая задача?

Расскажите контекст — подскажу, что и как делать.

Обсудить похожий проект →