Перейти к основному контенту
CI CONSULT
Загрузка...

Процесс загрузки книги после нажатия «Загрузить книгу»

Павел Молотивский

Разложение на этапы: Триггер → Обработчик → Запрос к 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)