К блогу

Админ-панель: пользователи и дайджест

Админ-панель — ваш центр управления продуктом без отдельного SaaS для админов. Всё встроено в то же приложение, те же компоненты Mantine, та же auth-сессия — но с дополнительной проверкой роли по email.

Доступ к /admin и всем вложенным маршрутам имеют только пользователи, чей email есть в ADMIN_EMAILS (app/lib/config/admin.ts). Список задаётся через переменную окружения, разделитель — запятая. В development добавьте свой email до первого входа.

Главная админки /admin показывает AdminDigestDashboard: сводные метрики за последние сутки — регистрации, активные подписки, выручка, события аналитики. Это быстрый «пульс» без погружения в детальный дашборд.

Страница /admin/users — таблица пользователей с поиском, датой регистрации, текущим тарифом и статусом подписки. Полезно для поддержки: найти аккаунт по email, проверить, оплатил ли пользователь, когда истекает план.

Аналитика на /admin/analytics — полноценный дашборд. AnalyticsStatCards: DAU, всего событий, конверсия. AnalyticsTrendChart: динамика по дням. AnalyticsFunnelChart: воронка от page_view до payment_succeeded. AnalyticsTopPagesTable и AnalyticsEventsTable — детализация.

Данные для дашборда читаются из rollup-таблиц через query.server.ts, а не из сырых миллионов events. Rollup обновляется фоновой джобой analytics.server.ts (pg-boss) по расписанию. Задержка в несколько минут между событием и графиком — нормальна.

Сырые события хранятся с ограниченным TTL. purge.server.ts периодически удаляет старые записи из analytics_events, чтобы таблица не раздувалась. Агрегаты в rollup остаются для исторических отчётов.

Daily digest — email-отчёт для админов за вчерашний день. Реализован в daily-digest.server.ts, отправляется cron-задачей. Содержит ключевые цифры: новые пользователи, платежи, топ событий. Настройте SMTP и ADMIN_EMAILS до включения в production.

Безопасность: не полагайтесь только на скрытие ссылки /admin. Проверка в loader обязательна на каждом admin-маршруте. Пентест: залогиньтесь обычным пользователем и попробуйте открыть /admin/analytics напрямую — должен быть 403 или redirect.

При масштабировании команды можно заменить ADMIN_EMAILS на роль в БД (поле isAdmin у user). Шаблон намеренно держит простой список email — для MVP этого достаточно, миграция на роли тривиальна.

Компоненты админки изолированы в app/components/admin/. При кастомизации не смешивайте admin-логику с пользовательским dashboard — разные аудитории, разные требования к плотности информации.

Аналитика в админке уважает приватность: журнал событий не показывает пароли и полный контент сообщений агентов. Если нужен PII для support — смотрите /admin/users, а не raw events.