Update .gitignore to include local environment files and expand README with project details, tech stack, documentation links, and project status.

This commit is contained in:
Leonid Pershin
2026-07-01 18:37:54 +03:00
parent 3b364cf8c4
commit d8930409fe
14 changed files with 1780 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
# Frontend
SPA на **React 19 + Vite + TypeScript**. Общается с бэком по REST (JWT Bearer) и получает
живые обновления по SignalR. Типы API генерируются из OpenAPI-схемы бэкенда.
> **Раздача из единого контейнера.** В проде собранный фронт (`dist/`) кладётся в `wwwroot`
> ASP.NET Core и раздаётся тем же приложением (SPA-fallback на `index.html`). Фронт и бек — один
> origin, база API — относительный `/api`, SignalR — `/hubs/panel`. В dev Vite-сервер проксирует
> `/api` и `/hubs` на бэкенд. Детали упаковки — [architecture.md](architecture.md#развёртывание-единый-контейнер-приложения).
## Стек
| Задача | Выбор |
| ----------------- | --------------------------------------- |
| Сборка/dev | Vite |
| Язык | TypeScript (strict) |
| Данные с сервера | TanStack Query |
| Роутинг | TanStack Router (типобезопасный) |
| UI-компоненты | shadcn/ui + Tailwind CSS v4 |
| Иконки | lucide-react |
| Клиентский стейт | Zustand (auth, тема) |
| Формы | react-hook-form + zod |
| Realtime | @microsoft/signalr |
| Графики | Recharts |
| QR-коды | qrcode.react |
| Типы API | openapi-typescript / orval (codegen) |
| i18n | react-i18next (RU + EN) |
| Пакетный менеджер | pnpm |
## Структура
```
frontend/
src/
app/ # провайдеры (Query, Router, Auth, Theme), корневой layout
routes/ # маршруты TanStack Router (login, dashboard, configs, admin/*)
features/
auth/ # формы, хуки useLogin/useRegister, стор авторизации
configs/ # список/создание/детали конфигов, QR, ссылка-подписка
nodes/ # (admin) управление нодами
admin/ # пользователи, статистика
shared/
api/ # http-клиент (fetch + JWT/refresh), сгенерированные типы, query-хуки
realtime/ # инициализация SignalR, подписки → инвалидация Query-кэша
ui/ # обёртки над shadcn/ui, общие компоненты
lib/ # утилиты, форматирование (байты, даты)
config/ # env, константы
styles/ # tailwind, темы
index.html
vite.config.ts
package.json
```
## Дизайн / UX
- **Тема оформления**: светлая и тёмная (переключатель в шапке; вариант «системная»). Реализация —
Tailwind `dark` (класс на `html`) + shadcn/ui; выбор сохраняется (localStorage).
- **Современный и чистый вид**: shadcn/ui + Tailwind, адаптивность, аккуратная типографика.
- **Дашборд пользователя**: карточки конфигов (протокол, локация, трафик прогресс-баром, срок, статус),
быстрые действия (копировать ссылку, показать QR, перевыпустить, отозвать) + карточка «Общая подписка»
(агрегированная ссылка/QR со всеми конфигами). Для неактивированного — экран «запросить активацию».
- **Создание конфига**: выбор локации/inbound (по `DisplayName`) + метка + лимит устройств →
мгновенная выдача ссылки + QR + краткие инструкции по подключению (iOS/Android/Windows).
- **Редактирование конфига**: изменить метку и лимит устройств.
- **Настройки аккаунта**: смена пароля, привязка/отвязка Telegram, **удаление аккаунта** (с подтверждением).
- **Админка**: таблицы (TanStack Table) с пагинацией/фильтрами для нод, пользователей, конфигов, ролей,
журнала аудита; очередь запросов активации; графики трафика (Recharts). Блокировка пользователя — с
подтверждением (гасит VPN).
- **Состояния**: скелетоны при загрузке, аккуратные пустые состояния и toasts на ошибки/успех.
## Работа с API
- HTTP-клиент оборачивает `fetch`: подставляет access-token, при 401 — прозрачно обновляет через
refresh-cookie и повторяет запрос; при неуспехе — разлогин.
- Все запросы/мутации — через TanStack Query (ключи по фичам, инвалидация после мутаций).
- Типы ответов/запросов — из codegen по OpenAPI (никакого ручного дублирования DTO).
## Авторизация на клиенте
- **Access-token** — в памяти (не в localStorage), кладётся в `Authorization: Bearer`.
- **Refresh-token** — httpOnly Secure cookie (JS не читает), ротация на сервере.
- Стор авторизации (Zustand) хранит профиль/роли/`isActivated`; guard-маршруты по роли (`admin` vs обычный)
и по активации (неактивированного ведём на экран «запросить активацию»).
- **Вход — по username** (email не используется). «Забыли пароль?» ведёт: при привязанном
Telegram — восстановление через бота; иначе — подсказка обратиться к админу.
- **Баннер привязки Telegram**: пока Telegram не привязан, показываем настойчивый, но не блокирующий
баннер/напоминание — это единственный self-service способ восстановить доступ. Настройки: смена пароля.
### Вход и привязка через Telegram
- **«Войти через Telegram»**: `POST /api/auth/telegram/login-request` → показать deep-link/QR на
бота, затем ждать подтверждения (поллинг `GET …/login-request/{id}` или событие SignalR). При
`Approved` — сохранить access, refresh уже в cookie, редирект в панель.
- **«Привязать Telegram»** (в настройках, для вошедшего): `POST /api/auth/telegram/link-token`
показать deep-link/QR; статус привязки обновить по факту (поллинг/SignalR). Отвязка — `unlink`.
- QR для deep-link — `qrcode.react`.
## Realtime
- Одно SignalR-подключение к `/hubs/panel` с JWT; реконнект с бэкоффом.
- Обработчики событий (`configTrafficUpdated`, `configStatusChanged`, `nodeStatusChanged`) точечно
обновляют/инвалидируют кэш TanStack Query — UI обновляется без перезагрузки.
## Скрипты (ожидаемые)
```bash
pnpm dev # dev-сервер Vite
pnpm build # прод-сборка
pnpm preview # предпросмотр сборки
pnpm lint # ESLint
pnpm typecheck # tsc --noEmit
pnpm gen:api # генерация типов из OpenAPI-схемы бэкенда
```