Enhance user plan management and update related endpoints
- Added new configuration options for user plans in `.env.example`, including `Plans__MaxCustomConfigCount` and `Plans__MinCustomConfigCount`. - Introduced `MapPlanEndpoints` in `Program.cs` to handle plan-related API routes. - Implemented `SetUserPlan` endpoint in `RoleEndpoints` to allow admins to assign plans to users. - Removed deprecated role request approval endpoints from `AdminSupportEndpoints`. - Updated `ITelegramNotifier` and related classes to reflect changes in role request handling and payment notifications. - Refactored role management commands to remove `MaxConfigs` and focus on `MaxIpLimit` and billing settings. - Enhanced billing request handling to accommodate plan changes instead of role changes. - Updated various interfaces and command handlers to support new plan management features.
This commit is contained in:
+12
-27
@@ -33,12 +33,12 @@ Telegram-бот — **второй канал доставки** (presentation-
|
||||
Зарегистрироваться»; плюс кнопка «🌐 Сайт панели» со ссылкой на сайт, если задан `Telegram__PublicSiteUrl`
|
||||
(пусто — кнопки нет). Слэш-команды `/configs`/`/unlink` продолжают работать как раньше — кнопки лишь
|
||||
вызывают те же обработчики через callback (`menu:configs`/`menu:unlink`/`menu:back`).
|
||||
8. **Админ: обработка заявок на роль поддержки** — при новой заявке (`SupportTicket.Type ==
|
||||
RoleRequest`) админ получает сообщение с описанием (существующая роль либо параметры новой) и
|
||||
обоснованием, жмёт «✅ Одобрить / ❌ Отклонить» **прямо в Telegram, без захода на сайт** — одобрение
|
||||
создаёт роль (если новая) и назначает её пользователю той же командой, что и на сайте. Баг-репорты/
|
||||
предложения — только уведомление с кнопкой-ссылкой на сайт, без инлайн-действий (переписка и
|
||||
вложения удобнее там).
|
||||
8. **Админ: обработка заявок на продление поддержки** — при новой заявке
|
||||
(`SupportTicket.Type == ExtensionRequest`, только для billing-ролей) админ получает сообщение с
|
||||
числом запрошенных дней и обоснованием, жмёт «✅ Одобрить / ❌ Отклонить» **прямо в Telegram, без
|
||||
захода на сайт** — одобрение продлевает `BillingPaidUntil` той же командой, что и на сайте.
|
||||
Баг-репорты/предложения — только уведомление с кнопкой-ссылкой на сайт, без инлайн-действий
|
||||
(переписка и вложения удобнее там).
|
||||
|
||||
**Не реализовано:**
|
||||
- QR-картинкой и агрегированная подписка в самом боте (только текстовая ссылка на конфиг по кнопке).
|
||||
@@ -49,6 +49,7 @@ Telegram-бот — **второй канал доставки** (presentation-
|
||||
просмотр списка и показ существующей ссылки по кнопке).
|
||||
- Баг-репорты/предложения тикетов поддержки **не решаются из бота** (только уведомление-ссылка) —
|
||||
ответы, вложения, resolve/close только на сайте.
|
||||
- Смена тарифа (`ChangePlanCommand`) — только на сайте (`/plan`), в боте не решается.
|
||||
|
||||
## Размещение в архитектуре
|
||||
|
||||
@@ -182,23 +183,8 @@ Telegram ──updates──► TelegramBotHostedService → PnvBotUpdateHandl
|
||||
(`InlineKeyboardButton.WithUrl`, не callback) — тап открывает страницу тикета в браузере.
|
||||
3. Дальше — только на сайте: переписка, вложения, resolve/close.
|
||||
|
||||
**Заявка на роль** — полностью решается в Telegram:
|
||||
1. `CreateRoleRequestTicketCommandHandler` вызывает
|
||||
`ITelegramNotifier.NotifyAdminsRoleRequestCreatedAsync(ticketId, userName, roleDescription, justification, ct)`
|
||||
— `roleDescription` уже готовая строка (имя существующей роли либо «новая роль «X» (конфигов: N, IP: M)»).
|
||||
2. Сообщение с кнопками **«✅ Одобрить» / «❌ Отклонить»** (callback `rrq:approve:{id}`/`rrq:reject:{id}`
|
||||
— тот же 3-частный формат `prefix:action:guid`, что и `act:*` для активации).
|
||||
3. Нажатие → проверка прав (`TrySetAdminCurrentUserAsync`, тот же, что для активации) →
|
||||
`ApproveRoleRequestCommand`/`RejectRoleRequestCommand` (те же команды, что дёргает
|
||||
`POST /api/admin/support/tickets/{id}/approve|reject` на сайте). При одобрении — если роль новая,
|
||||
сперва создаётся `AppRole`, затем в любом случае назначается пользователю; тикет переходит в
|
||||
`Resolved`/`Closed`. Нажавшему админу — короткое подтверждение, исходное сообщение редактируется
|
||||
(дописывается статус), как и у `act:*`.
|
||||
4. Пользователю (если Telegram привязан) — DM «✅ Ваша заявка на роль одобрена.» / «❌ Ваша заявка на
|
||||
роль отклонена.».
|
||||
|
||||
**Заявка на продление** (`ExtensionRequest`, только для billing-ролей) — тот же паттерн, что и заявка
|
||||
на роль, инлайн-кнопки с префиксом `erq:`:
|
||||
**Заявка на продление** (`ExtensionRequest`, только для billing-ролей) — полностью решается в
|
||||
Telegram, инлайн-кнопки с префиксом `erq:`:
|
||||
1. `CreateExtensionRequestTicketCommandHandler` вызывает
|
||||
`ITelegramNotifier.NotifyAdminsExtensionRequestCreatedAsync(ticketId, userName, requestedDays, justification, ct)`.
|
||||
2. Кнопки **«✅ Одобрить» / «❌ Отклонить»** (callback `erq:approve:{id}`/`erq:reject:{id}`).
|
||||
@@ -213,7 +199,7 @@ Telegram ──updates──► TelegramBotHostedService → PnvBotUpdateHandl
|
||||
|
||||
Только для ролей с `AppRole.BillingEnabled` (см. [domain-model.md](domain-model.md#billing--подписка-по-сроку)).
|
||||
Заявка (`PaymentRequest`) заводится и решается частично на сайте, частично в Telegram — симметрично
|
||||
заявке на роль:
|
||||
заявке на продление:
|
||||
|
||||
1. Пользователь создаёт заявку и жмёт «Я оплатил» на сайте (`/billing`) — бот в это не вовлечён,
|
||||
кроме опциональной кнопки «Отправить реквизиты в Telegram» (DM самому себе для удобства, статус
|
||||
@@ -221,11 +207,11 @@ Telegram ──updates──► TelegramBotHostedService → PnvBotUpdateHandl
|
||||
2. `MarkPaymentSentCommandHandler` вызывает
|
||||
`ITelegramNotifier.NotifyAdminsPaymentRequestedAsync(requestId, userName, period, amount, ct)`.
|
||||
3. Сообщение с кнопками **«✅ Подтвердить» / «❌ Отклонить»** (callback `pay:approve:{id}`/`pay:reject:{id}`
|
||||
— тот же 3-частный формат, что и `rrq:*`/`act:*`).
|
||||
— тот же 3-частный формат, что и `erq:*`/`act:*`).
|
||||
4. Нажатие → проверка прав (`TrySetAdminCurrentUserAsync`) → `ConfirmPaymentRequestCommand`/
|
||||
`RejectPaymentRequestCommand` (те же команды, что дёргает `POST /api/admin/billing/requests/{id}/confirm|reject`
|
||||
на сайте). Подтверждение продлевает `AppUser.BillingPaidUntil` и возвращает приостановленные
|
||||
конфиги в `Active`. Исходное сообщение редактируется (дописывается статус), как у `rrq:*`/`act:*`.
|
||||
конфиги в `Active`. Исходное сообщение редактируется (дописывается статус), как у `erq:*`/`act:*`.
|
||||
5. Пользователю (если Telegram привязан) — DM «✅ Оплата подтверждена. Доступ продлён до {дата}.» /
|
||||
«❌ Заявка на оплату отклонена.».
|
||||
|
||||
@@ -261,7 +247,6 @@ Telegram ──updates──► TelegramBotHostedService → PnvBotUpdateHandl
|
||||
| «📝 Зарегистрироваться» (`reg:new`) | Регистрация нового аккаунта прямо из бота (Флоу 3) | нет (нужно, чтобы **не** был привязан) |
|
||||
| «✅ Активировать»/«❌ Отклонить» | (admin) решение по конкретному запросу активации | админ по env |
|
||||
| `/requests` | (admin) список ожидающих запросов активации (до 10) | админ по env |
|
||||
| «✅ Одобрить»/«❌ Отклонить» (`rrq:*`) | (admin) решение по заявке на роль — создаёт/назначает роль | админ по env |
|
||||
| «✅ Одобрить»/«❌ Отклонить» (`erq:*`) | (admin) решение по заявке на продление — продлевает `BillingPaidUntil` | админ по env |
|
||||
| «✅ Подтвердить»/«❌ Отклонить» (`pay:*`) | (admin) решение по заявке на оплату — продлевает `BillingPaidUntil` | админ по env |
|
||||
| «🌐 Открыть на сайте» | Ссылка на баг-репорт на сайте (только если задан `Telegram__PublicSiteUrl`) | админ по env |
|
||||
|
||||
Reference in New Issue
Block a user