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