Перейти к содержанию

Админ-панель

Админ-панель — это отдельное окно в Miami Graphics доступное только аккаунтам с ролью Admin или Moderator в Supabase. Здесь делается вся работа по управлению каталогом: загрузка новых модов, разбор, генерация превью, утверждение пользовательских заявок.

Сайдбар админ-панели с 13 секциями

Кто видит

HunterGraphics.Shell/Bridge/AppBridge.cs
public async Task<AuthResultDto> AuthenticateUserAsync(string login, string password, string? totp)
{
    var user = await _userRepo.FindByLoginAsync(login);
    var ok = VerifyPassword(password, user.PasswordHash);
    if (!ok) throw new UnauthorizedException();

    // ... TOTP check если включен ...

    return new AuthResultDto(
        token: GenerateLocalToken(user.Id),
        role: user.Role,           // 'Admin' / 'Moderator' / 'User' / 'Guest'
        username: user.Username
    );
}

UI скрывает админ-панель если role != 'Admin' && role != 'Moderator':

const hasAdmin = auth?.role === 'Admin' || auth?.role === 'Moderator';
{hasAdmin && <SidebarItem icon={ShieldIcon} label="Админ" onClick={() => navigate('admin')} />}

Это client-side hide, не security. Реальная защита на стороне Supabase RLS — все admin-операции требуют JWT с правильным role claim.

Структура

Админ-панель это single-page wizard с боковой навигацией. 12 секций:

flowchart LR
  AdminSidebar[Sidebar] --> Settings[Settings — глобальные настройки]
  AdminSidebar --> Redux[Redux — каталог модов]
  AdminSidebar --> Guns[Guns — оружейные паки]
  AdminSidebar --> Armor[Бронежилеты]
  AdminSidebar --> DlcImport[DLC Import]
  AdminSidebar --> Injector[Injector — manual install]
  AdminSidebar --> Database[Database]
  AdminSidebar --> GtaVersions[GTA Versions]
  AdminSidebar --> Library[Library — отдельные компоненты]
  AdminSidebar --> Presets[GTA Presets — графика]
  AdminSidebar --> Builds[Заявки на сборки]
  AdminSidebar --> ProPlayers[PRO Players]
  AdminSidebar --> Popularity[Popularity]

Каждая секция — отдельный экран с своим CRUD UI и pipeline'ом операций.

Главное правило

Все записи в БД и R2 идут через Bridge handlers в AppBridge. UI не имеет прямого доступа к Supabase или R2 — все запросы идут через C# код где включена авторизация и валидация.

// плохо — никогда не делаем так:
await supabase.from('redux_items').insert(...);

// хорошо:
await bridge.adminCatalogUpdateAsync(item);

Это даёт:

  • Single point control над permissions;
  • Возможность включить server-side валидацию (SHA проверки, формат файлов);
  • Audit trail (логирование в debug-log что и кто менял).

Workflow upload нового мода

Самый типичный для админа сценарий:

sequenceDiagram
    participant A as Admin (UI)
    participant Bridge as AppBridge
    participant Parser as ReduxParserPipeline
    participant R2 as Cloudflare R2
    participant Supa as Supabase

    A->>Bridge: adminReduxAnalyze(modRpfPath)
    Bridge->>Parser: ParseRedux(cleanRpf, modRpf, name)
    Parser->>Parser: open archives, diff, scan components
    Parser-->>Bridge: ReduxAnalysisDto {actions, components, glb}
    Bridge-->>A: показать preview

    A->>Bridge: adminQueueAdd(item)
    Bridge->>R2: upload patch.zip
    Bridge->>R2: upload preview.png
    Bridge->>R2: upload armor.glb (если есть)
    Bridge->>R2: upload per-component files
    Bridge->>Supa: insert redux_items + redux_versions rows
    Bridge-->>A: success, новый мод в каталоге

Это происходит за 30 секунд – 2 минуты в зависимости от размера мода. Тяжёлая работа — это R2 upload (200-500 МБ типично) и parse pipeline.

Дальше: Redux секция →