GymTeam
Управление клубами: одна платформа, много клубов
Сторона персонала в экосистеме Fitofan: спортивные клубы ведут участников, занятия, чекин, прогресс и платежи, каждый клуб — в собственном приватном пространстве.
- Роль
- Senior Full-Stack Engineer
- Период
- 2025 – 2026


Контекст
GymTeam — это рабочее место владельцев клубов, менеджеров и тренеров; атлеты и родители пользуются Fitofan, который также их аутентифицирует. Я выделил его из кодовой базы Fitofan в отдельный продукт и сделал большую его часть.
Задача
Обслуживать много независимых клубов из одного приложения со строгой изоляцией данных, принимать платежи на каждом рынке, где работают клубы, и держать данные клубов согласованными с платформой атлетов в реальном времени.
Реализовано на всех уровнях стека
- Админка на Next.js 16 по Feature-Sliced Design: 80+ страниц, 11 локалей
- Бэкенд на NestJS: модуль на каждую сущность с use case'ами, репозиториями и валидированными DTO; 95 миграций
- Изоляция тенантов: guard резолвит каждый клуб по id или slug и проверяет членство до запуска любого обработчика
- Участники, приглашения и пробные занятия, недельные расписания с листами ожидания, живой чекин, посещаемость, учебная программа и уровни поясов, отказы от ответственности, домашние задания, оценивание
- Платежи: Finix, Stripe, PayPal, Square, Monopay, LiqPay, GCash и Mercado Pago плюс наличные и долги, ежедневный планировщик биллинга, хранение учётных данных с AES-256-GCM
- Контракт RabbitMQ, общий с Fitofan: 29 ключей маршрутизации, типизированный конверт с корреляционными идентификаторами, задокументированная топология
- Вход по QR через WebSockets, шлюз сессий Socket.IO, S3-совместимое хранилище медиа
- Аналитика доходов, посещаемости и тренеров с экспортом в CSV и PDF
- Тот же конвейер поставки, что и у Fitofan: гейт проверки типов и Jest, Docker-образ, деплой через SSH
Инженерные акценты
- Границы тенанта обеспечиваются на сервере, а не доверяются клиенту
- Вебхуки идемпотентны по провайдеру и id события; платёжные намерения несут ключи идемпотентности
- Собственное правило ESLint со своими тестами держит слои Feature-Sliced честными
- Сценарии регистрации и создания клуба приходят из пакетов, общих для обоих продуктов
Что это даёт
Каждый клуб получает продукт, который ощущается сделанным именно для него, а инженерия остаётся одной кодовой базой и одним деплоем.