496 lines
13 KiB
Markdown
496 lines
13 KiB
Markdown
# Demo API Guide для Лэндинга
|
||||
|
|
|
|||
|
|
## Обзор
|
|||
|
|
|
|||
|
|
Demo API предоставляет функционал для демонстрации основных возможностей платформы NoCopy на лэндинге без необходимости регистрации пользователя.
|
|||
|
|
|
|||
|
|
## Ключевые Особенности
|
|||
|
|
|
|||
|
|
✅ **Анонимная загрузка файлов** - без авторизации
|
|||
|
|
✅ **Хранение в S3** - безопасное облачное хранилище
|
|||
|
|
✅ **Автоматическая очистка** - удаление через 24 часа
|
|||
|
|
✅ **Ограничения по IP** - защита от злоупотреблений
|
|||
|
|
✅ **Размер лимитов** - до 50 MB на файл, 10 файлов в день
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## API Эндпоинты
|
|||
|
|
|
|||
|
|
### 1. Загрузка файла
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
POST /api/demo/upload
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Параметры:**
|
|||
|
|
- `file` (required) - файл для загрузки (jpg, png, pdf, docx, mp3 и т.д.)
|
|||
|
|
|
|||
|
|
**Примеры ответа:**
|
|||
|
|
|
|||
|
|
✅ Успех (200 OK):
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|||
|
|
"fileName": "document.pdf",
|
|||
|
|
"fileType": "document",
|
|||
|
|
"fileSize": 1048576,
|
|||
|
|
"status": "COMPLETED",
|
|||
|
|
"message": "File uploaded successfully",
|
|||
|
|
"uploadedBytes": 1048576,
|
|||
|
|
"progressPercentage": 100
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
❌ Файл слишком большой (400):
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": null,
|
|||
|
|
"fileName": null,
|
|||
|
|
"fileType": null,
|
|||
|
|
"fileSize": 0,
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "File too large. Max size: 50 MB",
|
|||
|
|
"uploadedBytes": 0,
|
|||
|
|
"progressPercentage": 0
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
❌ Лимит на день превышен (400):
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": null,
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "Daily limit reached. Max 10 files per day"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. Получение информации о файле
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
GET /api/demo/file/{sessionId}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Параметры:**
|
|||
|
|
- `sessionId` (path) - ID сессии из ответа загрузки
|
|||
|
|
|
|||
|
|
**Ответ (200 OK):**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|||
|
|
"fileName": "document.pdf",
|
|||
|
|
"fileType": "document",
|
|||
|
|
"fileSize": 1048576,
|
|||
|
|
"status": "COMPLETED",
|
|||
|
|
"createdAt": "2025-07-01T10:30:00Z",
|
|||
|
|
"expiresAt": "2025-07-02T10:30:00Z",
|
|||
|
|
"searchResultsCount": null,
|
|||
|
|
"mimeType": "application/pdf"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. Запуск поиска похожих файлов
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
POST /api/demo/search/{sessionId}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Параметры:**
|
|||
|
|
- `sessionId` (path) - ID сессии
|
|||
|
|
|
|||
|
|
**Ответ (200 OK):**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|||
|
|
"status": "COMPLETED",
|
|||
|
|
"resultsCount": 3,
|
|||
|
|
"matchPercentage": 92.5,
|
|||
|
|
"startedAt": "2025-07-01T10:31:00Z",
|
|||
|
|
"completedAt": "2025-07-01T10:31:05Z",
|
|||
|
|
"processingTimeMs": 5000,
|
|||
|
|
"similarFiles": [
|
|||
|
|
{
|
|||
|
|
"fileId": "demo_abc123",
|
|||
|
|
"fileName": "similar_image_1.jpg",
|
|||
|
|
"similarityScore": 0.95,
|
|||
|
|
"source": "web"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"fileId": "demo_def456",
|
|||
|
|
"fileName": "similar_image_2.png",
|
|||
|
|
"similarityScore": 0.90,
|
|||
|
|
"source": "database"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"fileId": "demo_ghi789",
|
|||
|
|
"fileName": "duplicate_document.pdf",
|
|||
|
|
"similarityScore": 0.85,
|
|||
|
|
"source": "web"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"message": "Search completed successfully"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. Очистка сессии
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
DELETE /api/demo/cleanup/{sessionId}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Параметры:**
|
|||
|
|
- `sessionId` (path) - ID сессии
|
|||
|
|
|
|||
|
|
**Ответ (200 OK):**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|||
|
|
"status": "CLEANED",
|
|||
|
|
"message": "Session cleaned successfully",
|
|||
|
|
"progressPercentage": 100
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 5. Health Check
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
GET /api/demo/health
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Ответ (200 OK):**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "HEALTHY",
|
|||
|
|
"message": "Demo service is ready"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Лимиты и Ограничения
|
|||
|
|
|
|||
|
|
| Параметр | Значение | Описание |
|
|||
|
|
|----------|----------|----------|
|
|||
|
|
| Max файл | 50 MB | Максимальный размер одного файла |
|
|||
|
|
| Файлов в день | 10 | Максимум файлов с одного IP в день |
|
|||
|
|
| TTL сессии | 24 часа | Время жизни демо-сессии |
|
|||
|
|
| Cleanup интервал | 30 минут | Как часто очищаются истекшие файлы |
|
|||
|
|
| Поддерживаемые типы | image, document, audio | Типы файлов для демо |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Поддерживаемые Типы Файлов
|
|||
|
|
|
|||
|
|
**Изображения:**
|
|||
|
|
- JPG/JPEG (.jpg, .jpeg)
|
|||
|
|
- PNG (.png)
|
|||
|
|
- GIF (.gif)
|
|||
|
|
- WebP (.webp)
|
|||
|
|
|
|||
|
|
**Документы:**
|
|||
|
|
- PDF (.pdf)
|
|||
|
|
- Word (.docx, .doc)
|
|||
|
|
- Excel (.xlsx, .xls)
|
|||
|
|
- Text (.txt)
|
|||
|
|
|
|||
|
|
**Аудио:**
|
|||
|
|
- MP3 (.mp3)
|
|||
|
|
- WAV (.wav)
|
|||
|
|
- M4A (.m4a)
|
|||
|
|
- OGG (.ogg)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Примеры использования
|
|||
|
|
|
|||
|
|
### cURL
|
|||
|
|
|
|||
|
|
**Загрузка файла:**
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://localhost:8080/api/demo/upload \
|
|||
|
|
-F "file=@document.pdf"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Получение информации:**
|
|||
|
|
```bash
|
|||
|
|
curl http://localhost:8080/api/demo/file/550e8400-e29b-41d4-a716-446655440000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Запуск поиска:**
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://localhost:8080/api/demo/search/550e8400-e29b-41d4-a716-446655440000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Очистка:**
|
|||
|
|
```bash
|
|||
|
|
curl -X DELETE http://localhost:8080/api/demo/cleanup/550e8400-e29b-41d4-a716-446655440000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### JavaScript
|
|||
|
|
|
|||
|
|
**Загрузка файла:**
|
|||
|
|
```javascript
|
|||
|
|
const formData = new FormData();
|
|||
|
|
formData.append('file', fileInput.files[0]);
|
|||
|
|
|
|||
|
|
const response = await fetch('http://localhost:8080/api/demo/upload', {
|
|||
|
|
method: 'POST',
|
|||
|
|
body: formData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const result = await response.json();
|
|||
|
|
const sessionId = result.sessionId;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Получение информации:**
|
|||
|
|
```javascript
|
|||
|
|
const info = await fetch(`http://localhost:8080/api/demo/file/${sessionId}`)
|
|||
|
|
.then(r => r.json());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Запуск поиска:**
|
|||
|
|
```javascript
|
|||
|
|
const search = await fetch(`http://localhost:8080/api/demo/search/${sessionId}`, {
|
|||
|
|
method: 'POST'
|
|||
|
|
})
|
|||
|
|
.then(r => r.json());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Python
|
|||
|
|
|
|||
|
|
**Загрузка файла:**
|
|||
|
|
```python
|
|||
|
|
import requests
|
|||
|
|
|
|||
|
|
files = {'file': open('document.pdf', 'rb')}
|
|||
|
|
response = requests.post('http://localhost:8080/api/demo/upload', files=files)
|
|||
|
|
result = response.json()
|
|||
|
|
session_id = result['sessionId']
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Обработка Ошибок
|
|||
|
|
|
|||
|
|
### 400 Bad Request - Файл слишком большой
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "File too large. Max size: 50 MB"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Решение:** Загрузите файл меньшего размера
|
|||
|
|
|
|||
|
|
### 400 Bad Request - Неподдерживаемый тип файла
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "File type not supported for demo"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Решение:** Используйте поддерживаемый тип файла
|
|||
|
|
|
|||
|
|
### 400 Bad Request - Лимит на день
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "Daily limit reached. Max 10 files per day"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Решение:** Подождите до следующего дня или зарегистрируйтесь
|
|||
|
|
|
|||
|
|
### 404 Not Found - Сессия не найдена
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "ERROR"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Решение:** Проверьте правильность sessionId
|
|||
|
|
|
|||
|
|
### 500 Internal Server Error
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"status": "FAILED",
|
|||
|
|
"message": "Upload failed: ..."
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Решение:** Попробуйте позже или свяжитесь с поддержкой
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Cleanup-сервис (важное объяснение)
|
|||
|
|
|
|||
|
|
### Что делает Cleanup-сервис?
|
|||
|
|
|
|||
|
|
Это автоматизированный сервис, который периодически:
|
|||
|
|
|
|||
|
|
1. **Ищет истекшие сессии** (старше 24 часов)
|
|||
|
|
2. **Удаляет файлы из S3** для экономии места
|
|||
|
|
3. **Помечает сессии как CLEANED** в БД
|
|||
|
|
4. **Удаляет FAILED сессии** (старше 1 часа)
|
|||
|
|
|
|||
|
|
### Почему это нужно?
|
|||
|
|
|
|||
|
|
- **Экономия дискового пространства** - S3 стоит денег
|
|||
|
|
- **Соблюдение GDPR/приватности** - данные не лежат вечно
|
|||
|
|
- **Производительность БД** - не растёт бесконечно
|
|||
|
|
- **Безопасность** - временные данные не остаются в системе
|
|||
|
|
|
|||
|
|
### Как это работает?
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Каждые 30 минут:
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ 1. Найти истекшие сессии │
|
|||
|
|
│ WHERE expiresAt <= NOW() │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
↓
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ 2. Для каждой сессии: │
|
|||
|
|
│ - Удалить из S3 │
|
|||
|
|
│ - Обновить статус = CLEANED │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### В конфиге (application.yaml):
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
demo:
|
|||
|
|
max-file-size: 52428800 # 50 MB
|
|||
|
|
max-files-per-day: 10 # макс 10 файлов в день
|
|||
|
|
s3-path: demo/ # путь в S3
|
|||
|
|
session-ttl-hours: 24 # 24 часа жизни сессии
|
|||
|
|
cleanup-interval: 30 # cleanup каждые 30 минут
|
|||
|
|
failed-cleanup-interval: 60 # очистка FAILED каждый час
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Статистика и Мониторинг
|
|||
|
|
|
|||
|
|
### Метрики для отслеживания
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// Количество активных демо-сессий
|
|||
|
|
long activeSessions = demoCleanupService.getActiveDemoSessionsCount();
|
|||
|
|
|
|||
|
|
// Общий размер демо-данных в S3
|
|||
|
|
long dataSizeInBytes = demoCleanupService.getActiveDemoDataSize();
|
|||
|
|
long dataSizeInMB = dataSizeInBytes / (1024 * 1024);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Логирование
|
|||
|
|
|
|||
|
|
Все операции логируются:
|
|||
|
|
```
|
|||
|
|
[INFO] Demo upload started for IP: 192.168.1.1
|
|||
|
|
[INFO] File uploaded to S3 at: demo/550e8400.../test.jpg
|
|||
|
|
[INFO] Starting search for session: 550e8400-e29b-41d4...
|
|||
|
|
[INFO] Demo cleanup completed. Cleaned 5 sessions
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Best Practices для Frontend
|
|||
|
|
|
|||
|
|
1. **Показывайте progress** - используйте `progressPercentage`
|
|||
|
|
2. **Обрабатывайте ошибки** - проверяйте `status` == "FAILED"
|
|||
|
|
3. **Очищайте сессии** - вызывайте `/cleanup` перед уходом
|
|||
|
|
4. **Не перезагружайте** - максимум 10 файлов в день
|
|||
|
|
5. **Таймауты** - сессия истекает через 24 часа
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Интеграция на лэндинге
|
|||
|
|
|
|||
|
|
### Step 1: Drag & Drop зона
|
|||
|
|
```html
|
|||
|
|
<div id="dropZone" class="upload-area">
|
|||
|
|
Перетащите файл сюда или нажмите
|
|||
|
|
<input type="file" id="fileInput" />
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 2: Загрузка
|
|||
|
|
```javascript
|
|||
|
|
const upload = async (file) => {
|
|||
|
|
const formData = new FormData();
|
|||
|
|
formData.append('file', file);
|
|||
|
|
|
|||
|
|
const res = await fetch('/api/demo/upload', {
|
|||
|
|
method: 'POST',
|
|||
|
|
body: formData
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return res.json();
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 3: Демо поиска
|
|||
|
|
```javascript
|
|||
|
|
const startDemo = async (sessionId) => {
|
|||
|
|
const res = await fetch(`/api/demo/search/${sessionId}`, {
|
|||
|
|
method: 'POST'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return res.json();
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 4: Очистка
|
|||
|
|
```javascript
|
|||
|
|
const endDemo = async (sessionId) => {
|
|||
|
|
await fetch(`/api/demo/cleanup/${sessionId}`, {
|
|||
|
|
method: 'DELETE'
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## FAQ
|
|||
|
|
|
|||
|
|
**Q: Мой файл исчезает через 24 часа?**
|
|||
|
|
A: Да, это запланировано. Используйте полную версию для постоянного хранения.
|
|||
|
|
|
|||
|
|
**Q: Могу ли я загрузить больше 10 файлов?**
|
|||
|
|
A: Только если зарегистрируетесь. Демо имеет лимиты в целях защиты.
|
|||
|
|
|
|||
|
|
**Q: Почему мне не дают загрузить файл больше 50 MB?**
|
|||
|
|
A: Это демо, которое работает на общих ресурсах. Полная версия поддерживает файлы до 1 GB.
|
|||
|
|
|
|||
|
|
**Q: Где хранятся мои файлы?**
|
|||
|
|
A: В AWS S3, в отдельной папке `demo/`. Никто другой не может получить к ним доступ.
|
|||
|
|
|
|||
|
|
**Q: Что если мой IP заблокирован?**
|
|||
|
|
A: Попробуйте через день или зарегистрируйтесь для безлимитного доступа.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Мониторинг Health
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
curl http://localhost:8080/api/demo/health
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Если получите `"status": "HEALTHY"` - все работает.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Последнее обновление:** 2026-07-01
|
|||
|
|
**Версия API:** 1.0.0
|
|||
|
|
**Статус:** Production Ready
|