Files
anti-plagiarism/docs/ARCHITECTURE.md
jze9 ea5c3a962c docs: визуальная схема системы (Mermaid) — docs/DIAGRAM.md
Диаграмма компонентов и потоков данных (frontend/API/очереди/воркеры/общая
инфра/опциональные Qdrant и Prometheus-Grafana) + sequence-диаграмма конвейера
проверки плагиата L1-L4. Дополняет текстовое ARCHITECTURE.md, на который
ссылается. ARCHITECTURE.md теперь ссылается на DIAGRAM.md и INGESTION.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-24 13:47:45 +05:00

14 KiB
Raw Blame History

Архитектура — Академический помощник

Каноничное описание системы. Обновляется вместе с кодом; при расхождении верить коду, а не этому файлу. Визуальная схема — DIAGRAM.md. Смежные документы: DR-HA.md (отказоустойчивость), INGESTION.md (наполнение корпуса), ../README.md (быстрый старт и команды).

1. Назначение

Веб-сервис для студентов: ввёл тему → система находит открытые академические источники, делает изложения, форматирует список литературы по ГОСТ и проверяет текст на плагиат. Всё асинхронно: пользователь отправляет задачу, закрывает браузер и получает результат на email (или в реальном времени через WebSocket, если вкладка открыта).

2. Общая схема

                         ┌────────────────────────────┐
                         │  Frontend (React SPA)       │  CT 102 → nginx
                         │  Home/Search/Check/Cabinet/ │
                         │  Bibliography/Settings/Admin │
                         └──────────────┬──────────────┘
                                        │ HTTPS (/api, /ws)
                         ┌──────────────▼──────────────┐
                         │  API Gateway (FastAPI)       │  1.32:8000
                         │  JWT · rate-limit · WebSocket │
                         │  /metrics (Prometheus)        │
                         └───┬───────────────────────┬──┘
                             │ publish (RabbitMQ)    │ read/write
                             │                       │
        ┌────────────────────┼───────────────────┐  │
        ▼                    ▼                   ▼  │
  queue.index          queue.gpu           queue.gost
  ┌───────────┐      ┌────────────┐      ┌───────────┐
  │ worker-   │      │ worker-gpu │      │ worker-   │
  │ indexer   │      │ FAISS/Qdr. │      │ gost      │
  │ L1 Winnow │      │ L3 семант. │      │ ГОСТ 7.1/ │
  │ L2 MinHash│      │ L4 LLM     │      │ 7.0.5     │
  │ PDF/DOCX  │      │ эмбеддинги │      │           │
  └─────┬─────┘      └──────┬─────┘      └─────┬─────┘
        │                   │                  │
        └─────────┬─────────┴───────┬──────────┘
                  ▼                  ▼
            queue.notify       общие данные
          ┌────────────┐   ┌──────────────────────────────┐
          │ worker-    │   │ PostgreSQL 1.38 · Redis 1.35  │
          │ notifier   │   │ RabbitMQ .82 · MinIO 1.21     │
          │ SMTP email │   │ Elasticsearch (local 1.32)    │
          └────────────┘   │ Ollama .163 (qwen2.5:7b)      │
                           │ [opt] Qdrant · Prometheus/Graf.│
                           └──────────────────────────────┘

3. Сервисы

Сервис Технологии Ответственность
api FastAPI, SQLAlchemy async (asyncpg), Redis, Celery-producer HTTP/WS API, auth (JWT), rate-limits, диспетч задач в очереди, админ-панель
worker-indexer Celery, PyMuPDF, python-docx, xxhash, datasketch Извлечение текста (PDF/DOCX/TXT), фрагментация, L1 Winnowing, L2 MinHash LSH, парсинг источников, обогащение full-text
worker-gpu Celery, sentence-transformers, FAISS/Qdrant, httpx→Ollama Эмбеддинги, L3 семантический поиск, L4 LLM-анализ парафраза, семантический поиск источников
worker-gost Celery Список литературы по ГОСТ 7.1-2003 / Р 7.0.5-2008
worker-notifier Celery, smtplib Email: письма-результаты и верификация (jze9mail.ru)
frontend React 18, Vite, TS, Tailwind, Zustand, React Query SPA: 11 публичных страниц + админ-панель. Собирается в статику, отдаётся nginx

4. Модель данных (PostgreSQL)

  • users — email, hashed_password (bcrypt), name, is_verified, is_admin, plan (free/student/premium), verification_token.
  • tasks — id (UUID), public_id (внешний), user_id, type (TaskType: search/plagiarism/summarize/gost), status (TaskStatus: queued→processing→done/failed), celery_task_id, input_data (JSON), result (JSON), error, queue_position.
  • documents — корпус источников: source (openalex/arxiv/cyberleninka/ user_submission), ext_id, doi, title, authors (JSON), year, lang, journal/volume/issue/pages, abstract, url, minio_key (full-text в MinIO), faiss_id.
  • fingerprints — doc_id, hash_value (BIGINT, Winnowing), position — для L1.
  • usage_logs — user_id, action — учёт лимитов по тарифу.
  • parse_sources — задания парсеров (админка): тип, query, годы, лимит, статус.
  • staged_works — пользовательские загрузки на модерацию перед добавлением в корпус.
  • admin_sessions — одноразовые коды входа в админку.

5. Асинхронный конвейер (Celery + RabbitMQ)

Брокер — RabbitMQ, backend результатов — Redis. Маршрутизация по префиксу задачи:

Очередь Задачи Воркер
queue.index index.extract_and_check, index.add_document, index.run_parser, index.enrich_full_text worker-indexer
queue.gpu gpu.check_plagiarism, gpu.embed_documents, gpu.search_semantic worker-gpu
queue.gost gost.format_bibliography worker-gost
queue.notify notify.send_task_done, notify.send_verification worker-notifier

Важно: API коммитит задачу в БД до send_task (иначе гонка dispatch-before-commit).

6. Ключевые потоки

Проверка плагиата. upload (api, файл→MinIO, Task) → index.extract_and_check (извлечь текст → фрагментация → L1 Winnowing по fingerprints → L2 MinHash LSH в Redis) → передаёт частичные совпадения в gpu.check_plagiarism (L3 FAISS/Qdrant семантика по фрагментам → для подозрительных L4 Ollama-парафраз) → app.scoring.aggregate_results (итоговый %) → результат в Task → notify.send_task_done.

Поиск источников. api → gpu.search_semantic: эмбеддинг запроса → векторный поиск (FAISS/Qdrant) + Elasticsearch BM25 → объединение → результат.

Список литературы. api → gost.format_bibliography: документы из БД → app.bibliography.build_bibliography (сортировка кириллица→латиница, нумерация, формат 7.1/7.0.5) → результат.

Наполнение корпуса. админка/CLI → index.run_parser (OpenAlex/arXiv/КиберЛенинка, фильтр is_oa) → index.add_document (дедуп по ext_id, fingerprints, MinHash, эмбеддинг) → index.enrich_full_text (скачать OA-PDF → MinIO → переиндексация).

7. Детекция плагиата — 4 уровня

  1. L1 Winnowing (worker-indexer/app/algorithms/winnowing.py) — точные/частичные совпадения: k-граммы → xxHash → минимум в скользящем окне → fingerprint; Jaccard.
  2. L2 MinHash LSH (.../minhash.py) — нечёткие совпадения: шинглы → MinHash (128 перм.) → LSH-индекс в общем Redis (префикс antiplag_lsh, upsert, graceful-фолбэк в память).
  3. L3 семантика (worker-gpu) — эмбеддинги paraphrase-multilingual-mpnet-base-v2 (768d, нормированы) → cosine в FAISS IndexIDMap2(IndexFlatIP) или Qdrant (VECTOR_BACKEND); порог 0.75.
  4. L4 LLM-парафраз — Ollama qwen2.5:7b оценивает пары «источник↔фрагмент» для подозрительных из L3; порог confidence 0.7.

Итог: scoring.aggregate_results — доля уникальных помеченных позиций (не выше 100%).

8. Векторный бэкенд

Абстрагирован за worker-gpu/app/vector_store.get_backend(); VECTOR_BACKEND=faiss (файловый синглтон, дефолт) или qdrant (сервис, снимает SPOF/конкурентную запись). Переключение и миграция — см. README, раздел «Векторный бэкенд».

9. Инфраструктура и топология

Компонент Узел Примечание
api + воркеры + Elasticsearch 1.32 (app-хост) docker-compose.prod.yml
Frontend (nginx, статика + TLS) CT 102 деплоится отдельно
PostgreSQL 16 1.38 (выделенный LXC) UTF8; бэкап→MinIO
Redis 7 1.35 (выделенный LXC) кэш, rate-limits, LSH
RabbitMQ 192.168.20.82 брокер Celery
MinIO (S3) 1.21 документы, full-text, бэкапы
Ollama (qwen2.5:7b) 192.168.20.163 GPU-сервер
Qdrant / Prometheus / Grafana 1.32 опционально, под compose-профилями

Деплой — Gitea Actions по push в main: гейт test (ruff+mypy → 82 юнит-теста), затем deploy (needs: test) через scripts/deploy.sh (умная пересборка изменённых сервисов). PG/Redis не в compose — общая инфра берётся из .env.

10. Конфигурация

Всё через .env (пример — .env.example). Обязательно менять: SECRET_KEY, POSTGRES_PASSWORD, MINIO_SECRET_KEY. Опции: VECTOR_BACKEND, QDRANT_URL, GRAFANA_ADMIN_PASSWORD. .env не в git и исключён из деплой-rsync (не откатывается).

11. Качество и тесты

  • 82 юнит-теста (pytest, per-service) на чистую логику L1-L4/скоринг/фрагменты/ ГОСТ/библиография; инфра замокана или не нужна. Запуск: make test.
  • Гейты CI: ruff (весь Python) + mypy (доменная логика) + тесты — блокируют деплой. make lint. Хермет-раннеры в python:3.11-slim.
  • Чистая доменная логика вынесена из Celery-задач в тестируемые модули (scoring.py, fragments.py, bibliography.py). Подробнее — README «Тестирование».

12. Наблюдаемость и эксплуатация

  • Мониторинг: antiplag_monitor.py (cron 5 мин, 7 сервисов, email-алерт при смене статуса). Опционально — Prometheus+Grafana (профиль observability, метрики API + Flower).
  • Бэкапы: pg_dump→gzip→MinIO, cron 03:00, ротация 14. Проверка восстановления — scripts/ops/pg_restore_verify.sh. HA/DR — DR-HA.md.

13. Безопасность

JWT-аутентификация, bcrypt-хэши паролей, email-верификация, отдельный вход в админку (одноразовые коды, admin_sessions). Rate-limits по тарифу — в Redis. CORS — явные origins. Пользователь видит только свои задачи (ownership проверяется, в т.ч. на WebSocket).

14. Раскладка репозитория

services/         api, worker-{gpu,indexer,notifier,gost}, frontend
scripts/          parsers/ (OpenAlex/arXiv/КиберЛенинка), ops/, deploy.sh,
                  run_tests.sh, run_lint.sh
infra/            nginx/, prometheus/, grafana/
docs/             ARCHITECTURE.md (этот файл), DR-HA.md
.gitea/workflows/ deploy.yml (гейт test → deploy)
ruff.toml · mypy.ini · Makefile · docker-compose.prod.yml