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:
@@ -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.
|
||||
Reference in New Issue
Block a user