ДАВАЙ ПОЧИНИМ

Платформа для поиска мастеров и заказа услуг

28+
API Endpoints
16
Таблиц в БД
4
Модуля
15%
Комиссия

Аутентификация через SMS

Безопасная авторизация по номеру телефона с SMS-подтверждением

Ввод телефона
SMS код
JWT токен
Доступ к API
POST /api/v1/auth/sms/send Отправить SMS код
Запрос
{ "phone": "+79991234567" }
Ответ (200 OK)
{ "success": true, "message": "SMS код отправлен", "expires_in": 300 }
POST /api/v1/auth/sms/verify Подтвердить SMS код
Запрос
{ "phone": "+79991234567", "code": "1234" }
Ответ (200 OK)
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 1800 }
POST /api/v1/auth/refresh Обновить токен
Запрос
{ "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
Ответ (200 OK)
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 1800 }
GET /api/v1/auth/me Получить текущего пользователя
Заголовки
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Ответ (200 OK)
{ "id": 1, "phone": "+79991234567", "name": "Иван Петров", "email": "ivan@example.com", "role": "user", "is_active": true, "created_at": "2024-01-15T10:30:00Z" }

Управление пользователями

Профиль, настройки и данные пользователя

GET /api/v1/users/profile Получить профиль
Ответ (200 OK)
{ "id": 1, "phone": "+79991234567", "name": "Иван Петров", "email": "ivan@example.com", "avatar_url": "https://storage.example.com/avatars/1.jpg", "address": "Москва, ул. Ленина 10", "orders_count": 5, "rating": 4.8 }
PUT /api/v1/users/profile Обновить профиль
Запрос
{ "name": "Иван Петров", "email": "ivan@example.com", "address": "Москва, ул. Пушкина 15" }
Ответ (200 OK)
{ "success": true, "message": "Профиль обновлен" }
GET /api/v1/users/orders Мои заказы
Параметры запроса
?status=pending&limit=10&offset=0
Ответ (200 OK)
{ "items": [ { "id": 1, "title": "Ремонт смесителя", "status": "pending", "budget": 2000, "created_at": "2024-01-15T10:30:00Z" } ], "total": 5, "limit": 10, "offset": 0 }

Управление заказами

Создание, поиск и управление заказами на услуги

POST /api/v1/orders/ Создать заказ
Запрос
{ "category_id": 1, required "title": "Ремонт смесителя на кухне", required "description": "Течет смеситель, нужна замена прокладки или полная замена", "budget": 3000, "address": "Москва, ул. Ленина 10, кв. 5", required "desired_date": "2024-01-20", "photos": ["base64_image_data..."] }
Ответ (201 Created)
{ "id": 42, "title": "Ремонт смесителя на кухне", "status": "pending", "lat": 55.7558, "lon": 37.6173, "created_at": "2024-01-15T10:30:00Z" }
GET /api/v1/orders/nearby Заказы рядом
Параметры запроса
?lat=55.7558&lon=37.6173&radius_km=10&category_id=1
Ответ (200 OK)
{ "items": [ { "id": 42, "title": "Ремонт смесителя", "budget": 3000, "distance_km": 2.5, "address": "Москва, ул. Ленина 10" }, { "id": 43, "title": "Установка розеток", "budget": 2000, "distance_km": 4.1, "address": "Москва, пр. Мира 25" } ], "total": 15 }
GET /api/v1/orders/{id} Детали заказа
Ответ (200 OK)
{ "id": 42, "title": "Ремонт смесителя на кухне", "description": "Течет смеситель, нужна замена прокладки", "category": { "id": 1, "name": "Сантехника" }, "budget": 3000, "status": "pending", "address": "Москва, ул. Ленина 10", "lat": 55.7558, "lon": 37.6173, "customer": { "id": 1, "name": "Иван П.", "rating": 4.8 }, "responses_count": 3, "created_at": "2024-01-15T10:30:00Z" }
POST /api/v1/orders/{id}/cancel Отменить заказ
Запрос
{ "reason": "Нашел мастера сам" }
Ответ (200 OK)
{ "success": true, "message": "Заказ отменен" }

Исполнители (Мастера)

Регистрация мастеров, отклики на заказы, портфолио

POST /api/v1/specialists/register Стать исполнителем
Запрос
{ "bio": "Профессиональный сантехник с опытом 10 лет", "experience_years": 10, "category_ids": [1, 2], "work_radius_km": 15, "base_address": "Москва, м. Таганская" }
Ответ (201 Created)
{ "id": 1, "user_id": 5, "bio": "Профессиональный сантехник с опытом 10 лет", "verified": false, "status": "pending_verification" }
POST /api/v1/specialists/orders/{id}/respond Откликнуться на заказ
Запрос
{ "price": 2500, "message": "Здравствуйте! Могу приехать сегодня. Опыт работы 10 лет.", "estimated_hours": 2 }
Ответ (201 Created)
{ "id": 15, "order_id": 42, "price": 2500, "status": "pending", "created_at": "2024-01-15T11:00:00Z" }
GET /api/v1/specialists/me Мой профиль исполнителя
Ответ (200 OK)
{ "id": 1, "bio": "Профессиональный сантехник", "experience_years": 10, "rating": 4.9, "reviews_count": 87, "completed_orders": 124, "verified": true, "balance": 15000, "categories": [ {"id": 1, "name": "Сантехника"}, {"id": 2, "name": "Электрика"} ] }
POST /api/v1/specialists/portfolio Добавить работу в портфолио
Запрос
{ "title": "Замена труб в ванной", "description": "Полная замена водопроводных труб", "photos": ["base64...", "base64..."], "category_id": 1 }
Ответ (201 Created)
{ "id": 5, "title": "Замена труб в ванной", "photos": [ "https://storage.example.com/portfolio/5_1.jpg", "https://storage.example.com/portfolio/5_2.jpg" ] }

Архитектура системы

Технологический стек и архитектурные решения

React/Next.js
Frontend
FastAPI
Backend
PostgreSQL
Database

Backend

  • FastAPI (Python 3.11+)
  • SQLAlchemy 2.0 (async)
  • Pydantic v2
  • Alembic (миграции)
  • JWT аутентификация
  • Redis (кеширование)

Frontend

  • React 18 / Next.js 14
  • TypeScript
  • Tailwind CSS
  • React Query
  • Zustand (состояние)
  • React Hook Form

База данных

  • PostgreSQL 15
  • PostGIS (геолокация)
  • 16 таблиц
  • Полнотекстовый поиск
  • Триггеры и индексы
  • Автообновление updated_at

Инфраструктура

  • Docker Compose
  • Nginx (reverse proxy)
  • Let's Encrypt SSL
  • Yandex Cloud S3
  • SMS.ru (верификация)
  • YooMoney (платежи)

Бизнес-модель

Комиссия 15%

  • 10% - с заказчика
  • 5% - с исполнителя
  • Escrow платежи
  • Безопасные сделки

Монетизация

  • Комиссия с заказов
  • Премиум подписка
  • Продвижение в поиске
  • Верификация мастеров

Схема базы данных

16 таблиц с полной нормализацией

users
idSERIAL PK
phoneVARCHAR(20) UNIQUE
nameVARCHAR(100)
emailVARCHAR(255)
roleuser_role ENUM
is_activeBOOLEAN
created_atTIMESTAMP
specialists
idSERIAL PK
user_idINT FK → users
bioTEXT
experience_yearsINT
ratingDECIMAL(3,2)
verifiedBOOLEAN
work_radius_kmINT
orders
idSERIAL PK
customer_idINT FK → users
category_idINT FK → categories
titleVARCHAR(200)
descriptionTEXT
budgetDECIMAL(10,2)
statusorder_status ENUM
lat / lonDECIMAL(10,8)
categories
idSERIAL PK
nameVARCHAR(100)
slugVARCHAR(100) UNIQUE
parent_idINT FK → categories
iconVARCHAR(50)
is_activeBOOLEAN
order_responses
idSERIAL PK
order_idINT FK → orders
specialist_idINT FK → specialists
priceDECIMAL(10,2)
messageTEXT
statusresponse_status ENUM
reviews
idSERIAL PK
order_idINT FK → orders
author_idINT FK → users
target_idINT FK → users
ratingINT (1-5)
commentTEXT
payments
idSERIAL PK
order_idINT FK → orders
amountDECIMAL(10,2)
commissionDECIMAL(10,2)
statuspayment_status ENUM
yookassa_idVARCHAR(100)
messages
idSERIAL PK
chat_idINT FK → chats
sender_idINT FK → users
contentTEXT
is_readBOOLEAN
created_atTIMESTAMP