10 KiB
HTTP API
Этот документ описывает текущий HTTP API EUSRR. Полный список операций и схем ответов генерируется из кода; вручную поддерживаемый список endpoint-ов здесь намеренно не дублируется.
Источники истины
- URL верхнего уровня:
backend/api/urls.py - API v1:
backend/api/v1/urls.py - authentication:
backend/api/auth/ - OpenAPI tags и metadata:
backend/api/schema.py - frontend transport:
frontend/src/lib/api/client.ts - доменные frontend clients:
frontend/src/lib/api/ - проверка документации:
backend/tests/api/test_documentation.py
Если этот guide расходится с /api/schema/, верной считается OpenAPI-схема.
Локальный запуск
Backend запускается как ASGI-приложение. Один процесс обслуживает HTTP и WebSocket:
cd backend
python manage.py migrate
daphne -b 0.0.0.0 -p 8000 eusrr_backend.asgi:application
Frontend:
cd frontend
cp .env.example .env.local
npm install
npm run dev
Для стандартной локальной конфигурации:
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
NEXT_PUBLIC_WS_URL=ws://localhost:8000/ws/
Документация, доступная из приложения
| URL | Назначение |
|---|---|
/api/schema/ |
OpenAPI 3 schema |
/api/docs/ |
Swagger UI |
/api/redoc/ |
ReDoc |
/api/ws/schema/ |
AsyncAPI schema для /ws/ |
/api/ws/docs/ |
HTML-страница WebSocket API |
Эти страницы доступны без аутентификации. Бизнес-endpoint-ы по умолчанию требуют авторизованного пользователя и Django model permissions.
Пространства URL
| Prefix | Содержимое |
|---|---|
/api/auth/ |
JWT, QR login, регистрация, password reset, auth-сессии |
/api/v1/ |
Основной versioned REST API |
/api/v1/auth/ |
Runtime alias authentication API для старых клиентов; в OpenAPI не дублируется |
/api/v1/communications/ |
Чаты, сообщения и опросы |
/api/v1/notifications/ |
Уведомления, preferences и Web Push |
/api/v1/schedule/ |
Календари, события, правила, occurrences и relations |
/api/v1/procurement/ |
Закупки и оборудование |
/api/v1/finance/ |
Финансы и payroll |
/api/v1/tasks/ |
Задачи, доски и automation |
Версии /api/v2/ в текущем проекте нет. Не добавляйте ссылки на неё и не используйте старые VITE_API_URL/Vite-примеры: frontend построен на Next.js.
Аутентификация
Основной способ — JWT:
curl -X POST http://localhost:8000/api/auth/token/ \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"change-me"}'
Вместо email можно передать phone или phone_number. Успешный ответ содержит access и refresh.
Защищённый запрос:
curl http://localhost:8000/api/v1/employees/me/ \
-H 'Authorization: Bearer ACCESS_TOKEN'
Обновление access token:
curl -X POST http://localhost:8000/api/auth/token/refresh/ \
-H 'Content-Type: application/json' \
-d '{"refresh":"REFRESH_TOKEN"}'
Каждая пара токенов привязана к записи UserAuthSession через claim session_id. Удалённая или отозванная сессия инвалидирует и HTTP, и WebSocket-доступ. Управление сессиями:
GET /api/auth/sessions/DELETE /api/auth/sessions/{session_id}/POST /api/auth/sessions/logout-others/
Frontend хранит access/refresh token в localStorage, добавляет Bearer header, выполняет единичный refresh при 401 и повторяет исходный запрос. Ошибка refresh очищает локальную сессию.
Новые пароли проходят стандартные Django validators: минимум 8 символов, запрет полностью цифровых и общеупотребительных паролей, проверка сходства с данными пользователя там, где пользователь известен. LDAP/AD может применять более строгую доменную политику дополнительно.
DRF ограничивает анонимные запросы до 60/min, авторизованные — до 600/min. Для login действует отдельный предел 10/min, для registration и email/reset операций — 5/hour, refresh — 60/min. Значения задаются в REST_FRAMEWORK.DEFAULT_THROTTLE_RATES.
Формат запросов и ответов
- JSON используется по умолчанию.
- Для загрузки файлов передавайте
FormData; API client не устанавливаетContent-Typeвручную, чтобы браузер добавил multipart boundary. - Стандартная пагинация:
pageиpage_size, значение по умолчанию — 20. - Максимальный
page_sizeбазового paginator — 200. Клиенты, которым нужен полный справочник, обходят страницы по полюnext, а не запрашивают неограниченную выдачу. - Ручная выдача notifications ограничена 100 элементами; message history и messages-around — суммарно 100 сообщениями за запрос.
204 No Contentне содержит JSON-тело.401означает отсутствующую, истёкшую или отозванную auth-сессию.403означает, что пользователь распознан, но не имеет требуемого model/object permission.400обычно содержит field-level validation errors; не преобразуйте его в общий500на frontend.
Глобальный поиск не расширяет права пользователя: результаты чатов, сообщений, документов, календарных событий, заявлений, закупок и уведомлений повторно проверяются по object-level правилам соответствующего домена.
Frontend proxy
Browser вызывает относительные пути /api/.... Next.js route frontend/src/app/api/[...path]/route.ts проксирует их на ${NEXT_PUBLIC_BACKEND_URL}/api/... и сохраняет query string, authorization headers, multipart body и streaming GET responses.
Используйте собранный client:
import { apiClient } from "@/lib/api";
const currentUser = await apiClient.getCurrentUser();
Новый доменный API добавляется отдельным модулем в frontend/src/lib/api/ и подключается в frontend/src/lib/api/index.ts. Не создавайте второй fetch-wrapper и не встраивайте абсолютный backend URL в компоненты.
Communications API
Router публикует:
communications/chatscommunications/messagescommunications/polls
Кроме CRUD доступны actions для участников, ролей, поиска, истории, отметки прочитанного, загрузок, реакций, пересылки, bulk delete и голосований. Их точные URL и payload смотрите в Swagger: они формируются из backend/communications/api/viewsets.py.
Для отметки прочитанного используйте HTTP action:
POST /api/v1/communications/chats/{chat_id}/mark-read/
WebSocket action mark_read оставлен только как deprecated compatibility path и не выполняет запись.
Добавление endpoint-а
- Добавьте serializer, permissions и view/viewset в доменный модуль.
- Зарегистрируйте URL под
/api/v1/; unversioned бизнес-URL не добавляются. - Добавьте
extend_schemaтам, где drf-spectacular не может вывести контракт автоматически. - Проверьте, что object permissions фильтруют и list, и detail queryset.
- Добавьте backend tests для успешного запроса,
401,403, validation и ownership boundaries. - Добавьте или расширьте доменный frontend client.
- Убедитесь, что endpoint появился в
/api/schema/с правильным tag.
Проверка
cd backend
pytest tests/api/test_documentation.py tests/api/auth tests/api/v1
Точечные suites предпочтительнее ручной коллекции curl-команд. Для диагностики контракта:
curl -fsS http://localhost:8000/api/schema/ -H 'Accept: application/json'
При изменении WebSocket-протокола дополнительно обновите backend/docs/architecture/websocket-asyncapi.yaml и выполните realtime tests.
Типовые ошибки
404на/api/v2/...: такой версии нет; используйте/api/v1/....401после успешного login: проверьте, что отправляется access token, а auth-сессия не отозвана.- Повторяющиеся refresh-запросы: используйте общий
apiClient, в нём refresh уже сериализован. - CORS в локальной разработке: browser должен обращаться к Next.js
/api/...; прямой backend-доступ разрешён только origin-ам изCORS_ALLOWED_ORIGINS. - Ошибка загрузки файла: не задавайте multipart
Content-Typeвручную.