Процесс загрузки книги после нажатия «Загрузить книгу»
Павел Молотивский
Разложение на этапы: Триггер → Обработчик → Запрос к API → Форматирование → Отправка.
1. Триггер
Пользователь на странице веб-приложения загрузки книг (/book-upload) выбирает файл (PDF или EPUB) и нажимает кнопку «Загрузить книгу».
mermaid
flowchart LR
A[Выбор файла] --> B[Кнопка «Загрузить книгу»]
B --> C[Клик]
C --> D[handleUpload]
| Элемент | Где |
|---|---|
| Кнопка | express-server/public/book-upload/index.html — #uploadBtn |
| Событие | uploadBtn.addEventListener('click', handleUpload) |
| Условие | selectedFile задан (файл выбран через зону drag‑and‑drop или <input type="file">) |
2. Обработчик
В браузере выполняется handleUpload(): собирается форма, подготавливается запрос, показывается прогресс.
mermaid
flowchart TD
H[handleUpload] --> D[FormData]
D --> D1[formData.append 'file', selectedFile]
H --> X[XHR]
X --> X1[POST /api/book-upload]
X --> X2[Header X-Telegram-Init-Data]
X --> X3[progress → progressFill, progressText]
X --> X4[xhr.send formData]
| Действие | Код |
|---|---|
| Блокировка кнопки | uploadBtn.disabled = true, текст «Загрузка...» |
| Сбор тела запроса | FormData, formData.append('file', selectedFile) |
| Заголовок авторизации | xhr.setRequestHeader('X-Telegram-Init-Data', initData) (если открыто из Telegram) |
| Прогресс | xhr.upload.addEventListener('progress', …) → обновление полосы и процентов |
3. Запрос к API
Запрос приходит на сервер: маршрут, проверка доступа, приём файла.
mermaid
flowchart TD
API[POST /api/book-upload] --> MW1[checkTelegramAccess]
MW1 --> MW2[upload.single 'file']
MW2 --> R[Роут-обработчик]
MW1 --> V[validateTelegramInitData]
V --> S[Subscriber + User isEmployee]
S --> OK[req.telegramUser, req.subscriber]
| Этап | Файл | Описание |
|---|---|---|
| Маршрут | express-server/routes/bookUpload.js |
router.post('/', checkTelegramAccess, upload.single('file'), async (req, res) => { … }) |
| Доступ | bookUpload.js |
Проверка X-Telegram-Init-Data через токены CI Daily / Library / Book Library, поиск сотрудника в БД |
| Загрузка файла | multer (memory) |
Один файл, до 100 МБ, только .pdf / .epub |
| Результат | req.file (buffer, originalname, size), req.telegramUser, req.subscriber |
4. Форматирование
Сервер извлекает текст, получает метаданные и обложку, собирает объект книги.
mermaid
flowchart LR
subgraph Извлечение
F[req.file.buffer] --> PDF[PDF: extractTextFromPdf 5 стр.]
F --> EPUB[EPUB: extractTextFromEpub 3 гл.]
PDF --> T1[extractedText]
EPUB --> T1
EPUB --> M[title, author из OPF]
end
subgraph Анализ
T1 --> AI[bookService.analyzeBook]
AI --> AN[title, author, description]
end
subgraph Обложка
AN --> COV[searchBookCover]
COV --> R2C[uploadCoverToR2]
end
subgraph Данные книги
AN --> BD[bookData]
M --> BD
R2C --> BD
end
| Шаг | Сервис/метод | Вход | Выход |
|---|---|---|---|
| 1. Парсинг | documentAnalysisService.extractTextFromPdf(buffer, 5) |
PDF buffer | extractedText |
| 1. Парсинг | bookService.extractTextFromEpub(buffer, 3) |
EPUB buffer | extractedText, title, author (из OPF) |
| 2. Анализ | bookService.analyzeBook(extractedText, fileName, fileExtension) |
Текст + имя/расширение | title, author, description (при необходимости — через GEN API) |
| 3. Обложка | bookService.searchBookCover(title, author) |
Название, автор | URL обложки или null |
| 3. Обложка | bookService.uploadCoverToR2(coverUrl, title) |
URL обложки | URL в R2 |
| Итог | — | — | bookData: title, author, description, coverUrl, затем pdfUrl или epubUrl |
5. Отправка
Файл книги отправляется в хранилище, запись сохраняется в БД, клиенту возвращается ответ; при необходимости отправляется уведомление в Telegram.
mermaid
flowchart TD
subgraph Хранилище
BUF[file.buffer] --> R2[bookService.uploadBookFileToR2]
R2 --> KEY[books/pdf|epub/timestamp_hex_name]
KEY --> R2B[(Cloudflare R2)]
R2B --> FILE_URL[fileUrl]
end
subgraph База
FILE_URL --> BOOK[bookData.pdfUrl | bookData.epubUrl]
EX[findExistingBook] --> UP{existingBook?}
UP -->|Да| UPDATE[existingBook.update]
UP -->|Нет| CREATE[Book.create]
UPDATE --> SAVED[savedBook]
CREATE --> SAVED
end
subgraph Ответ и уведомления
SAVED --> RES[res.json success, title, author, bookId]
SAVED --> TG[sendTelegramNotification]
TG --> BOT[BOOK_LIBRARY_BOT_TOKEN]
end
| Действие | Где | Описание |
|---|---|---|
| Загрузка файла в R2 | bookService.uploadBookFileToR2(buffer, fileName, fileExtension) |
Имя: `books/{pdf |
| Поиск дубликата | bookService.findExistingBook(title, author) |
По нормализованным названию и автору |
| Сохранение | existingBook.update(updates) или Book.create(bookData) |
Добавление/обновление pdfUrl/epubUrl/coverUrl |
| Ответ клиенту | res.json({ success, title, author, bookId, message }) |
Успешный ответ после сохранения |
| Уведомление | sendTelegramNotification(chatId, savedBook, …) |
Сообщение в Telegram через BOOK_LIBRARY_BOT (если бот настроен) |
Сводная схема (все этапы)
mermaid
flowchart TB
subgraph Триггер
T1[Кнопка «Загрузить книгу»]
end
subgraph Обработчик_клиент
T1 --> H[handleUpload]
H --> FD[FormData + file]
FD --> XHR[XHR POST /api/book-upload]
end
subgraph Запрос_API
XHR --> AUTH[checkTelegramAccess]
AUTH --> MUL[multer.single 'file']
MUL --> ROUTE[Роут POST /]
end
subgraph Форматирование
ROUTE --> EXTRACT[extractText PDF/EPUB]
EXTRACT --> ANALYZE[analyzeBook]
ANALYZE --> COVER[searchBookCover + uploadCoverToR2]
COVER --> BOOK_DATA[bookData]
end
subgraph Отправка
BOOK_DATA --> R2[uploadBookFileToR2]
R2 --> DB[(Book create/update)]
DB --> RES[res.json]
DB --> TG[Telegram уведомление]
end
Триггер --> Обработчик_клиент
Обработчик_клиент --> Запрос_API
Запрос_API --> Форматирование
Форматирование --> Отправка
Файлы по этапам
| Этап | Файлы |
|---|---|
| 1. Триггер | express-server/public/book-upload/index.html (кнопка, handleUpload) |
| 2. Обработчик | express-server/public/book-upload/index.html (FormData, XHR, заголовки, прогресс) |
| 3. Запрос к API | express-server/routes/bookUpload.js (маршрут, checkTelegramAccess, upload.single) |
| 4. Форматирование | express-server/routes/bookUpload.js (оркестрация), express-server/services/bookService.js, express-server/services/documentAnalysisService.js |
| 5. Отправка | express-server/services/bookService.js (R2, БД), express-server/routes/bookUpload.js (res.json, sendTelegramNotification) |