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
+115
View File
@@ -0,0 +1,115 @@
# Backend Conventions
## Структура решения
```
backend/
PnvPanel.sln
src/
PnvPanel.Domain/
Common/ # Entity, AggregateRoot, IDomainEvent, ValueObject base
Nodes/ # Node, NodeCredentials, NodeStatus, события
Inbounds/ # Inbound, VpnProtocol
Configs/ # VpnConfig, ConfigStatus, TrafficLimit, события
Plans/ # Plan
Exceptions/ # DomainException и наследники
PnvPanel.Application/
Common/
Behaviors/ # Validation, Logging, UnitOfWork, Authorization
Interfaces/ # IAppDbContext, IXuiPanelGateway, ICurrentUser, IRealtimeNotifier, ...
Messaging/ # ISender, ICommand<T>, IQuery<T>, ICommandHandler<,>, IQueryHandler<,>, IPipelineBehavior<,>
Models/ # Result<T>, Error, PagedList<T>
Mapping/ # Mapster-конфиги
Auth/ # Register/Login/Refresh (Commands, Handlers, Validators, DTOs)
Configs/ # CreateVpnConfig, EditVpnConfig, RotateVpnConfig, RevokeVpnConfig, GetMyConfigs, GetConfigLink, GetSubscription, ...
Nodes/ # RegisterNode, SyncNode, ListNodes, ...
Inbounds/ # PublishInbound, ListInbounds, ...
Admin/ # ListUsers, BlockUser/UnblockUser, ChangeUserRole, GetStats, Audit, ...
PnvPanel.Infrastructure/
Persistence/
AppDbContext.cs
Configurations/ # IEntityTypeConfiguration<T>
Migrations/
Identity/ # AppUser, AppRole, JwtTokenService, RefreshToken
Xui/ # XuiPanelGateway, XuiClientFactory (per-node)
Realtime/ # SignalRRealtimeNotifier
BackgroundJobs/ # TrafficSyncService, NodeHealthCheckService
Security/ # DataProtectionSecretProtector
DependencyInjection.cs
PnvPanel.Api/
Endpoints/ # AuthEndpoints, ConfigEndpoints, NodeEndpoints, AdminEndpoints, SubscriptionEndpoints
Hubs/ # PanelHub
Middleware/ # ExceptionHandling, RequestCorrelation
Extensions/ # AddApiServices, UseApiPipeline
Program.cs
appsettings*.json
tests/
PnvPanel.Domain.Tests/
PnvPanel.Application.Tests/
PnvPanel.Integration.Tests/ # Testcontainers PostgreSQL
```
Организация Application — **по фичам** (feature folders), внутри слоёв Clean Architecture.
## Именование
- Классы/методы/свойства — `PascalCase`; параметры/локальные — `camelCase`; приватные поля — `_camelCase`.
- Команды — `<Verb><Noun>Command` (`CreateVpnConfigCommand`), запросы — `<Get/List><Noun>Query`.
- Хендлеры — `<Command/Query>Handler`; валидаторы — `<Command/Query>Validator`.
- DTO — суффикс `Dto` (`VpnConfigDto`); ответы эндпоинтов — `Response`, тела запросов — `Request`.
- Async-методы — суффикс `Async`, всегда принимают `CancellationToken`.
- Один публичный тип на файл; имя файла = имя типа.
## Паттерны
- **Rich domain model**: инварианты в сущностях (приватные сеттеры, фабричные методы `Node.Create(...)`,
поведенческие методы `config.Revoke()`), а не анемичные DTO-сущности.
- **CQRS через собственный диспетчер**: хендлеры реализуют `ICommandHandler<TCommand,TResult>` /
`IQueryHandler<,>`; `ISender` резолвит их из DI и прогоняет через `IPipelineBehavior<,>`
(валидация, транзакция, логирование). Без внешних CQRS-библиотек.
- **Порты в Application, адаптеры в Infrastructure**: никакого `Npgsql`/`SignalR`/`ThreeXui.Net` в Application/Domain.
- **`IAppDbContext`** экспонирует `DbSet<>` и `SaveChangesAsync`; хендлеры пишут LINQ напрямую
(репозитории — только для сложной агрегатной логики).
- **Result-модель**: команды/запросы возвращают `Result<T>`; эндпоинт маппит в HTTP (`.Match(...)`).
- **Транзакция на команду**: `UnitOfWorkBehavior` оборачивает выполнение команды в транзакцию.
- **Валидация**: `ValidationBehavior` до хендлера; хендлер не проверяет формат ввода повторно.
- **Идемпотентность**: команды к 3x-ui устойчивы к повторам; при частичном сбое — компенсация
(создали клиента в панели, но упала БД → удалить клиента, вернуть ошибку).
- **Оптимистичная блокировка**: на изменяемых сущностях (нода, конфиг) — `xmin`/rowversion, чтобы
параллельные правки не затирали друг друга.
## Работа с 3x-ui
- Только через порт `IXuiPanelGateway`. Гейтвей принимает `Node`/`NodeId` и разруливает per-node клиента.
- Пароли нод расшифровываются `ISecretProtector` **внутри** Infrastructure, никогда не покидают слой.
- Сетевые ошибки/недоступность → `Result.Failure`/статус ноды, не «пробрасываем» наружу как 500.
## Async / Cancellation
- Всё I/O — асинхронно; пробрасывать `CancellationToken` до EF Core и HTTP-вызовов.
- Не блокировать (`.Result`/`.Wait()`).
## Ошибки и логирование
- Единый `ProblemDetails` для ошибок API; коды: 400 (валидация), 401/403 (auth), 404, 409 (конфликт домена), 422, 429 (rate limit), 500.
- Serilog со структурными полями (`UserId`, `NodeId`, `ConfigId`, `CorrelationId`); секреты не логировать.
## Тестирование
- **Domain.Tests** — инварианты и поведение сущностей, без моков.
- **Application.Tests** — хендлеры с подменёнными портами (NSubstitute), проверка веток `Result`.
- **Integration.Tests** — реальный PostgreSQL (Testcontainers), миграции, сквозные сценарии эндпоинтов;
3x-ui — мок гейтвея или фейковый HTTP-сервер.
- Именование тестов: `Method_Scenario_ExpectedResult`.
## Конфигурация
- `appsettings.json` + `appsettings.{Environment}.json` + env vars (перекрывают).
- Секреты (JWT-ключ, строка подключения, ключ шифрования) — user-secrets (dev) / env/secret-store (prod).
- Строго типизированные `IOptions<T>` для секций конфига; валидация опций на старте.
## Стиль и качество кода
- `.editorconfig` + анализаторы (`Microsoft.CodeAnalysis.NetAnalyzers`), nullable reference types **включены**.
- `dotnet format` в CI; предупреждения как ошибки для наших проектов.
- Комментарии — по необходимости (почему, а не что); публичные контракты портов документируем XML-doc.