10 KiB
10 KiB
Nashel Backend
Бэкенд для маркетплейса услуг "Nashel" — платформа для поиска мастеров и исполнителей.
🏗️ Архитектура
Проект построен на архитектуре Clean Architecture с модульным подходом:
nashel-backend/
├── src/
│ ├── BuildingBlocks/ # Общие блоки для всех модулей
│ │ ├── Application/ # Общие абстракции и поведения
│ │ ├── Domain/ # Базовые доменные сущности
│ │ └── Infrastructure/ # Общая инфраструктура
│ ├── Modules/ # Модули бизнес-логики
│ │ ├── Identity/ # Модуль авторизации и профилей
│ │ └── Order/ # Модуль заказов
│ └── Host/ # Точка входа приложения
└── tests/ # Тесты
Модульность
Каждый модуль (Identity, Order) является автономным и содержит:
- Domain — бизнес-логика, сущности, репозитории
- Application — Use Cases, команды, запросы, валидация
- Infrastructure — реализация репозиториев, EF Core
- Presentation — API endpoints
🚀 Технологический стек
- .NET 10 — фреймворк
- ASP.NET Core — веб-фреймворк
- Entity Framework Core — ORM
- PostgreSQL — база данных
- MediatR — паттерн CQRS/Mediator
- FluentValidation — валидация
- JWT — аутентификация
- Docker — контейнеризация
- Swagger/OpenAPI — документация API
📦 Установка и запуск
Требования
- .NET 10 SDK
- Docker и Docker Compose
- PostgreSQL
Запуск через Docker Compose
# Клонирование репозитория
git clone <repository-url>
cd nashel-backend
# Запуск всех сервисов
docker-compose up -d
# Просмотр логов
docker-compose logs -f app
# Остановка сервисов
docker-compose down
Локальный запуск
# Восстановление зависимостей
dotnet restore
# Настройка переменных окружения
cp src/Host/appsettings.json src/Host/appsettings.Development.json
# Отредактируйте ConnectionStrings__DefaultConnection
# Применение миграций
dotnet ef database update --project src/Host --startup-project src/Host
# Запуск
dotnet run --project src/Host
🔧 Переменные окружения
| Переменная | Описание | Пример |
|---|---|---|
ASPNETCORE_ENVIRONMENT |
Окружение | Development, Production |
ConnectionStrings__DefaultConnection |
Строка подключения к БД | Host=db;Port=5432;Database=nashel;Username=postgres;Password=postgres |
JWT__Secret |
Секретный ключ JWT | your-super-secret-key |
JWT__Issuer |
Издатель токена | nashel-api |
JWT__Audience |
Аудитория токена | nashel-client |
JWT__ExpirationMinutes |
Время жизни токена (мин) | 60 |
📚 API Документация
Swagger доступен по адресу: http://localhost:5000/swagger
Основные эндпоинты
Аутентификация
POST /api/auth/register
Content-Type: application/json
{
"phone": "+79001234567",
"firstName": "Иван",
"lastName": "Иванов",
"password": "password123",
"confirmPassword": "password123",
"isCompany": false,
"companyName": "ООО 'Ромашка'",
"inn": "1234567890"
}
POST /api/auth/login
Content-Type: application/json
{
"phone": "+79001234567",
"password": "password123"
}
Профиль пользователя
GET /api/profile
Authorization: Bearer {access_token}
PUT /api/profile
Authorization: Bearer {access_token}
Content-Type: application/json
{
"firstName": "Иван",
"lastName": "Иванов",
"patronymic": "Иванович",
"companyName": "ООО 'Ромашка'",
"inn": "1234567890"
}
POST /api/profile/change-phone
Authorization: Bearer {access_token}
Content-Type: application/json
{
"newPhone": "+79009876543"
}
POST /api/profile/become-performer
Authorization: Bearer {access_token}
POST /api/profile/avatar
Authorization: Bearer {access_token}
Content-Type: multipart/form-data
avatar: <file>
PUT /api/profile/competencies
Authorization: Bearer {access_token}
Content-Type: application/json
{
"Competencies": ["сантехника", "электрика"]
}
Компетенции
GET /api/competencies/search?q=сантех
Authorization: Bearer {access_token}
🎯 Реализованный функционал
Модуль Identity
Аутентификация и авторизация
- ✅ Регистрация пользователей (частные лица и компании)
- ✅ Вход в систему (JWT токены)
- ✅ Обновление токенов
- ✅ Выход из системы
- ✅ Ролевая модель (Client, Master, Candidate, Company, Admin)
Профиль пользователя
- ✅ Получение профиля
- ✅ Редактирование профиля
- ✅ Изменение номера телефона
- ✅ Загрузка аватара с кропом
- ✅ Управление компетенциями
- ✅ Стать исполнителем
Компетенции
- ✅ Поиск компетенций по подстроке
- ✅ Общий пул компетенций для всех исполнителей
- ✅ Автоматическое создание новых компетенций
Компании
- ✅ Регистрация компаний с ИНН
- ✅ Управление данными компании
- ✅ Отдельная логика для компаний
Модуль Order (в разработке)
- ⏳ Создание заказов
- ⏳ Поиск заказов на карте
- ⏳ SLA таймер для отклика на заказы
🗄️ База данных
Схема
accounts (аккаунты пользователей)
├── id (PK)
├── phone (уникальный)
├── password_hash
├── roles (массив ролей)
└── profile_id (FK)
user_profiles (профили пользователей)
├── id (PK)
├── account_id (FK)
├── first_name
├── last_name
├── patronymic
├── company_name
├── inn (для компаний)
├── avatar_url
└── competency_profiles (связь с компетенциями)
competencies (компетенции/навыки)
├── id (PK)
├── name (уникальное, в нижнем регистре)
competency_profiles (связь профилей и компетенций)
├── id (PK)
├── profile_id (FK)
├── competency_id (FK)
Миграции
# Создание новой миграции
dotnet ef migrations add AddNewFeature --project src/Infrastructure --startup-project src/Host
# Применение миграций
dotnet ef database update --project src/Infrastructure --startup-project src/Host
# Откат последней миграции
dotnet ef database update --project src/Infrastructure --startup-project src/Host
🔐 Безопасность
- Хеширование паролей (BCrypt)
- JWT токены с refresh token
- Валидация входных данных (FluentValidation)
- CORS политика
- Rate limiting (в планах)
🧪 Тестирование
# Запуск всех тестов
dotnet test
# Запуск тестов с покрытием
dotnet test --collect:"XPlat Code Coverage"
# Запуск конкретного теста
dotnet test --filter "FullyQualifiedName~TestName"
📝 Конвенции кода
CQRS Pattern
Используем MediatR для реализации CQRS:
// Команда (Command)
public record UpdateProfileCommand(...) : IRequest;
// Обработчик команды (Handler)
public class UpdateProfileCommandHandler : IRequestHandler<UpdateProfileCommand>
{
public async Task Handle(UpdateProfileCommand request, CancellationToken cancellationToken)
{
// Логика
}
}
Валидация
Используем FluentValidation:
public class UpdateProfileCommandValidator : AbstractValidator<UpdateProfileCommand>
{
public UpdateProfileCommandValidator()
{
RuleFor(x => x.FirstName).NotEmpty().MinimumLength(2);
RuleFor(x => x.LastName).NotEmpty().MinimumLength(2);
}
}
🚨 Обработка ошибок
- Глобальный exception handler
- Стандартные HTTP статусы (400, 401, 403, 404, 500)
- Подробные сообщения об ошибках в Development режиме
- Обобщенные сообщения в Production режиме
📦 Статические файлы
Загруженные аватары хранятся в wwwroot/uploads/ и доступны по URL:
http://localhost:5000/uploads/{filename}
🔄 CI/CD
- GitHub Actions для автоматического тестирования
- Docker Hub для хранения образов
- Автоматический деплой (в планах)
📞 Контакты
- Проект: Nashel
- Версия: 1.0.0
- Лицензия: MIT
🤝 Вклад в проект
- Fork репозитория
- Создайте ветку для фичи (
git checkout -b feature/AmazingFeature) - Закоммитьте изменения (
git commit -m 'Add some AmazingFeature') - Запушьте в ветку (
git push origin feature/AmazingFeature) - Откройте Pull Request