Corp/docs/guides/API.md

182 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
```bash
cd backend
python manage.py migrate
daphne -b 0.0.0.0 -p 8000 eusrr_backend.asgi:application
```
Frontend:
```bash
cd frontend
cp .env.example .env.local
npm install
npm run dev
```
Для стандартной локальной конфигурации:
```dotenv
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/` | Совместимый alias authentication API |
| `/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:
```bash
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`.
Защищённый запрос:
```bash
curl http://localhost:8000/api/v1/employees/me/ \
-H 'Authorization: Bearer ACCESS_TOKEN'
```
Обновление access token:
```bash
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 очищает локальную сессию.
## Формат запросов и ответов
- JSON используется по умолчанию.
- Для загрузки файлов передавайте `FormData`; API client не устанавливает `Content-Type` вручную, чтобы браузер добавил multipart boundary.
- Стандартная пагинация: `page` и `page_size`, значение по умолчанию — 20.
- Максимальный `page_size`, принятый базовым paginator, — 10000. Для UI используйте существенно меньшие страницы.
- `204 No Content` не содержит JSON-тело.
- `401` означает отсутствующую, истёкшую или отозванную auth-сессию.
- `403` означает, что пользователь распознан, но не имеет требуемого model/object permission.
- `400` обычно содержит field-level validation errors; не преобразуйте его в общий `500` на frontend.
## 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:
```ts
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/chats`
- `communications/messages`
- `communications/polls`
Кроме CRUD доступны actions для участников, ролей, поиска, истории, отметки прочитанного, загрузок, реакций, пересылки, bulk delete и голосований. Их точные URL и payload смотрите в Swagger: они формируются из `backend/communications/api/viewsets.py`.
Для отметки прочитанного используйте HTTP action:
```text
POST /api/v1/communications/chats/{chat_id}/mark-read/
```
WebSocket action `mark_read` оставлен только как deprecated compatibility path и не выполняет запись.
## Добавление endpoint-а
1. Добавьте serializer, permissions и view/viewset в доменный модуль.
2. Зарегистрируйте URL под `/api/v1/`; unversioned бизнес-URL не добавляются.
3. Добавьте `extend_schema` там, где drf-spectacular не может вывести контракт автоматически.
4. Проверьте, что object permissions фильтруют и list, и detail queryset.
5. Добавьте backend tests для успешного запроса, `401`, `403`, validation и ownership boundaries.
6. Добавьте или расширьте доменный frontend client.
7. Убедитесь, что endpoint появился в `/api/schema/` с правильным tag.
## Проверка
```bash
cd backend
pytest tests/api/test_documentation.py tests/api/auth tests/api/v1
```
Точечные suites предпочтительнее ручной коллекции curl-команд. Для диагностики контракта:
```bash
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` вручную.