diff --git a/README.md b/README.md index 81f0d0f..9d72d4b 100644 --- a/README.md +++ b/README.md @@ -1,350 +1,138 @@ -# Nashel Backend +# 🔮 Nashel — Backend API -Бэкенд для маркетплейса услуг "Nashel" — платформа для поиска мастеров и исполнителей. +> **ASP.NET Core · Modular Monolith · PostgreSQL · Docker** -## 🏗️ Архитектура +Серверная часть платформы **Nashel** — маркетплейса для поиска и найма профессиональных исполнителей (мастеров, специалистов и компаний). Бэкенд построен по принципу **Модульного Монолита** с чёткой доменной изоляцией. -Проект построен на архитектуре **Clean Architecture** с модульным подходом: +--- + +## 🎯 Какую проблему решает Nashel + +В России огромное количество мастеров и специалистов, которые работают «по сарафанному радио» — без нормальных инструментов для привлечения клиентов. А клиенты, в свою очередь, тратят время на поиск через знакомых или ненадёжные сайты объявлений. + +**Nashel** — это: +- Удобный и быстрый поиск исполнителей **рядом с тобой** на карте +- Прозрачная система услуг с ценами, фото и описанием +- Система репутации и отзывов +- Безопасное взаимодействие клиента и исполнителя + +--- + +## 👤 Роли пользователей + +| Роль | Описание | +|------|----------| +| **Клиент** | Ищет услуги на карте, просматривает профили исполнителей, оставляет заявки | +| **Кандидат в мастера** | Зарегистрировался как исполнитель, проходит верификацию | +| **Мастер** | Верифицированный исполнитель — частный специалист, самозанятый | +| **Компания** | Юридическое лицо, предоставляющее услуги через платформу | + +--- + +## 🧱 Архитектура + +Проект реализован как **Modular Monolith** — единое приложение, разделённое на изолированные модули с чёткими границами. Каждый модуль содержит: ``` -nashel-backend/ -├── src/ -│ ├── BuildingBlocks/ # Общие блоки для всех модулей -│ │ ├── Application/ # Общие абстракции и поведения -│ │ ├── Domain/ # Базовые доменные сущности -│ │ └── Infrastructure/ # Общая инфраструктура -│ ├── Modules/ # Модули бизнес-логики -│ │ ├── Identity/ # Модуль авторизации и профилей -│ │ └── Order/ # Модуль заказов -│ └── Host/ # Точка входа приложения -└── tests/ # Тесты +Modules// +├── Application/ # Команды, запросы, DTO (MediatR) +├── Domain/ # Сущности, бизнес-логика, интерфейсы репозиториев +├── Infrastructure/ # Реализация репозиториев, EF Core DbContext +└── Presentation/ # HTTP Endpoints (Minimal API) ``` -### Модульность +### Модули -Каждый модуль (Identity, Order) является автономным и содержит: -- **Domain** — бизнес-логика, сущности, репозитории -- **Application** — Use Cases, команды, запросы, валидация -- **Infrastructure** — реализация репозиториев, EF Core -- **Presentation** — API endpoints +| Модуль | Назначение | +|--------|------------| +| **Identity** | Регистрация, авторизация (JWT), профиль, роли, аватар, геолокация, расписание | +| **Catalog** | Управление услугами (CRUD), изображения, статусы, атрибуты | +| **Geo** | Геозоны, расчёт расстояний (PostGIS / NetTopologySuite) | +| **Search** | Полнотекстовый поиск по услугам и компетенциям с учётом геопозиции | +| **Reputation** | Отзывы и рейтинги (в разработке) | +| **Collaboration** | Заявки и взаимодействие клиент ↔ исполнитель (в разработке) | +| **Order** | Заказы и их жизненный цикл (в разработке) | -## 🚀 Технологический стек +### Host -- **.NET 10** — фреймворк -- **ASP.NET Core** — веб-фреймворк -- **Entity Framework Core** — ORM -- **PostgreSQL** — база данных -- **MediatR** — паттерн CQRS/Mediator -- **FluentValidation** — валидация -- **JWT** — аутентификация -- **Docker** — контейнеризация -- **Swagger/OpenAPI** — документация API +`Host/` — точка входа приложения. Здесь настраиваются DI, middleware, маршрутизация и сборка всех модулей. -## 📦 Установка и запуск +--- -### Требования +## ✅ Что реализовано -- .NET 10 SDK -- Docker и Docker Compose -- PostgreSQL +### Аутентификация и профиль +- Регистрация и вход по логину/паролю (JWT токены) +- Смена пароля, обновление профиля +- Загрузка аватара (хранится как base64 в БД) +- Переход в роль исполнителя: описание, компетенции, геолокация -### Запуск через Docker Compose +### Геолокация +- Привязка основного адреса и текущего местоположения +- Расчёт расстояния до исполнителей с помощью **PostGIS + NetTopologySuite** +- Геозоны для фильтрации исполнителей в радиусе -```bash -# Клонирование репозитория -git clone -cd nashel-backend +### Услуги (Catalog) +- Создание, редактирование, удаление (soft delete) услуг +- Приостановка услуги (пауза) +- Загрузка до 10 изображений (≤5 МБ каждое), хранение в БД +- Атрибуты услуги (произвольные ключ-значение пары) +- Первое изображение является обложкой -# Запуск всех сервисов -docker-compose up -d +### Поиск +- Полнотекстовый поиск по: названию услуги, описанию, компетенциям +- Результаты сортируются с учётом расстояния и релевантности +- Исполнитель показывается в поиске только если у него нет найденных услуг (приоритет услуги над специалистом) +- Приостановленные и удалённые услуги не отображаются +- Возврат URL первого изображения услуги для превью в поиске -# Просмотр логов -docker-compose logs -f app +### Расписание и статус доступности +- Настройка рабочих дней и «всегда готов» +- Умная логика статуса: ручное включение статуса «Готов к заказу» переопределяет расписание до конца текущего дня -# Остановка сервисов -docker-compose down -``` - -### Локальный запуск - -```bash -# Восстановление зависимостей -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` - -### Основные эндпоинты - -#### Аутентификация - -```http -POST /api/auth/register -Content-Type: application/json - -{ - "phone": "+79001234567", - "firstName": "Иван", - "lastName": "Иванов", - "password": "password123", - "confirmPassword": "password123", - "isCompany": false, - "companyName": "ООО 'Ромашка'", - "inn": "1234567890" -} -``` - -```http -POST /api/auth/login -Content-Type: application/json - -{ - "phone": "+79001234567", - "password": "password123" -} -``` - -#### Профиль пользователя - -```http -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: - -PUT /api/profile/competencies -Authorization: Bearer {access_token} -Content-Type: application/json - -{ - "Competencies": ["сантехника", "электрика"] -} -``` - -#### Компетенции - -```http -GET /api/competencies/search?q=сантех -Authorization: Bearer {access_token} -``` - -## 🎯 Реализованный функционал - -### Модуль Identity - -#### Аутентификация и авторизация -- ✅ Регистрация пользователей (частные лица и компании) -- ✅ Вход в систему (JWT токены) -- ✅ Обновление токенов -- ✅ Выход из системы -- ✅ Ролевая модель (Client, Master, Candidate, Company, Admin) - -#### Профиль пользователя -- ✅ Получение профиля -- ✅ Редактирование профиля -- ✅ Изменение номера телефона -- ✅ Загрузка аватара с кропом -- ✅ Управление компетенциями -- ✅ Стать исполнителем - -#### Компетенции -- ✅ Поиск компетенций по подстроке -- ✅ Общий пул компетенций для всех исполнителей -- ✅ Автоматическое создание новых компетенций - -#### Компании -- ✅ Регистрация компаний с ИНН -- ✅ Управление данными компании -- ✅ Отдельная логика для компаний - -### Модуль Order (в разработке) -- ⏳ Создание заказов -- ⏳ Поиск заказов на карте -- ⏳ SLA таймер для отклика на заказы +--- ## 🗄️ База данных -### Схема +- **PostgreSQL** с расширением **PostGIS** (геопространственные запросы) +- **Entity Framework Core** (Code First, миграции) +- Структура: таблица `Accounts`, `Performers`, `Offers`, `Competencies` и др. -``` -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) -``` - -### Миграции +## 🐳 Запуск через Docker ```bash -# Создание новой миграции -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 +# Запуск базы данных и бэкенда +docker-compose up -d --build ``` -## 🔐 Безопасность +Настройки в `docker-compose.yml` (строка подключения, порты, переменные окружения). -- Хеширование паролей (BCrypt) -- JWT токены с refresh token -- Валидация входных данных (FluentValidation) -- CORS политика -- Rate limiting (в планах) +--- -## 🧪 Тестирование +## ⚙️ Локальный запуск ```bash -# Запуск всех тестов -dotnet test +cd nashel-backend -# Запуск тестов с покрытием -dotnet test --collect:"XPlat Code Coverage" +# Применить миграции +dotnet ef database update -p src/Host -s src/Host -# Запуск конкретного теста -dotnet test --filter "FullyQualifiedName~TestName" +# Запустить +dotnet run --project src/Host ``` -## 📝 Конвенции кода +Swagger UI доступен по адресу: `http://localhost:5000/swagger` -### CQRS Pattern +--- -Используем MediatR для реализации CQRS: - -```csharp -// Команда (Command) -public record UpdateProfileCommand(...) : IRequest; - -// Обработчик команды (Handler) -public class UpdateProfileCommandHandler : IRequestHandler -{ - public async Task Handle(UpdateProfileCommand request, CancellationToken cancellationToken) - { - // Логика - } -} -``` - -### Валидация - -Используем FluentValidation: - -```csharp -public class UpdateProfileCommandValidator : AbstractValidator -{ - 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 - -## 🤝 Вклад в проект - -1. Fork репозитория -2. Создайте ветку для фичи (`git checkout -b feature/AmazingFeature`) -3. Закоммитьте изменения (`git commit -m 'Add some AmazingFeature'`) -4. Запушьте в ветку (`git push origin feature/AmazingFeature`) -5. Откройте Pull Request +## 🔮 Планы развития +- [ ] Полный модуль **Collaboration**: чат между клиентом и исполнителем +- [ ] Модуль **Order**: жизненный цикл заказа, статусы, оплата +- [ ] Модуль **Reputation**: система отзывов и рейтингов (реальные данные вместо заглушек) +- [ ] Верификация документов исполнителя +- [ ] Push-уведомления +- [ ] Поддержка OAuth (VK, Google) +- [ ] Аналитика для исполнителей (просмотры, конверсии)