# Модуль: Кабинет администратора (Filament)

[← К оглавлению](../README.md)

Админка на **Filament 5** по адресу **`/admin`**. Доступ только `role=admin` (`User::canAccessPanel()`).

Вход: `admin@placeo.test` / `admin12345`.

## Панель

`app/Providers/Filament/AdminPanelProvider.php` — id `admin`, путь `/admin`, бренд «Placeo · Админка», основной цвет Lime, авто-дискавери ресурсов/страниц/виджетов.

## Ресурсы (`app/Filament/Resources/`)

| Ресурс | Группа | Возможности |
|---|---|---|
| **Categories** | Каталог | создание/редактирование, **перемещение ветки** (смена родителя — nestedset переносит поддерево), активация/скрытие, фильтр по разделу |
| **Ads** | Каталог | фильтры: раздел, статус, **цена от/до**, **период**, поиск по названию/продавцу; действия «Открыть», **«Заблокировать» с причиной из списка**, «Разблокировать» |
| **Users** | Площадка | поиск, роль, рейтинг, блок/разблок; **«Написать»** (сообщение от поддержки → support-тред); «Профиль» (публичная карточка) |
| **Reports** (жалобы) | Площадка | жалобы на **объявления и на продавцов**; столбцы «Объявление»/«Продавец», переходы «К объявлению»/«К продавцу», прямые действия **«Заблокировать объявление»/«Заблокировать продавца»**, «Рассмотрена»/«Отклонить»; бейдж новых жалоб в меню |
| **Pages** (страницы) | Контент | статические страницы (`/page/{slug}`): О проекте, Помощь, Политика и т.д. |
| **Articles** (блог) | Контент | статьи блога (`/blog`): обложка, автор, дата, редактор; slug транслитом. См. [blog.md](blog.md) |
| **AiUsages** (расходы ИИ) | Система | отчёт по расходам DeepSeek (только чтение), см. ниже |
| **PhoneCallLogs** (звонки-подтверждения) | Система | журнал заказанных обратных звонков (только чтение), см. ниже |

> Примечание: вместо мышиного drag-drop дерева категорий реализовано перемещение через выбор родителя (надёжно для ~2266 узлов). Drag-drop можно добавить отдельной задачей через tree-плагин/кастомную страницу.

## Дашборд

`app/Filament/Widgets/StatsOverview.php` — статистика: активные объявления, на модерации, заблокировано, пользователи, новые жалобы.

## Расходы ИИ (DeepSeek)

`app/Filament/Resources/AiUsages/` — раздел **Система → «Расходы ИИ»** (`/admin/ai-usages`, только чтение). Каждый вызов DeepSeek фиксируется в `ai_usages` (пишет `DeepSeekClient`). На странице: виджет с суммами за сегодня/7/30 дней/всего, таблица вызовов с привязкой к пользователю и объявлению, стоимостью и токенами; группировка по типу операции и по пользователю, фильтры по типу и датам, бейдж с расходом за месяц в меню. Прайс — в `config/services.php → deepseek.pricing`. Подробнее — [integrations.md](integrations.md).

## Звонки-подтверждения

`app/Filament/Resources/PhoneCallLogs/` — раздел **Система → «Звонки-подтверждения»**
(`/admin/phone-call-logs`, только чтение). Каждый дозвон списывается с баланса сервиса
подтверждения, поэтому каждая попытка пишется в `phone_call_logs` (пишет `PhoneService`).
Фильтры по исходу (`ok` / капча не пройдена / отказ провайдера / некорректный номер),
источнику (сайт, виджет, мини-апп, кабинет) и периоду; поиск по номеру и IP; бейдж —
число ушедших звонков за сутки. Таблица чистится по расписанию (`model:prune`, раз в сутки
в 03:30): отбитые попытки живут 30 дней, состоявшиеся звонки — год. Подробнее — [auth.md](auth.md).

## Настройки

`app/Filament/Pages/Settings.php` + `resources/views/filament/pages/settings.blade.php`:
- **DeepSeek-модерация**: тумблер `moderation_enabled` + API-ключ + модель;
- **Telegram-бот**: token + admin chat ID; кнопка **«Тест Telegram»**;
- **Защита от ботов (Яндекс SmartCaptcha)**: тумблер `captcha_enabled` + клиентский
  (`ysc1_…`) и серверный (`ysc2_…`) ключи — капча перед обратным звонком, см. [auth.md](auth.md);
- **«Разослать новость»** — рассылка `platform_news` всем пользователям.

Значения хранятся в `app/Models/Setting.php` (key-value, кэш) и читаются `ModerationService`/`TelegramService` приоритетнее `.env`.

## Telegram-алерты администратору

`app/Services/TelegramService.php` + `app/Jobs/SendTelegramAlert.php` (через очередь). Все алерты содержат ссылку на объект. Триггеры:
- новое объявление (`Cabinet/AdController`),
- блокировка модерацией DeepSeek (`Jobs/ModerateAd`),
- жалоба на объявление (`AdController@report`) и **на продавца** (`SellerController@report`).

> Для работы алертов/модерации запустите `php artisan queue:work`. Как узнать Telegram chat ID — см. [integrations.md](integrations.md).

См. также: [ads.md](ads.md), [messaging.md](messaging.md), [integrations.md](integrations.md).
