Files
rf4-spotter/README.md
T
2026-09-03 08:11:23 +07:00

7.3 KiB
Raw Blame History

RF4 Spotter

RF4 Spotter — неофициальный сервис свежих точек и статистики клёва для Russian Fishing 4. Этап 1 содержит контейнерный каркас, демоданные, read-only API, главную страницу и страницу точки. Реальный импорт официальных рекордов пока остаётся отдельным исследовательским адаптером этапа 0.

Запуск через Docker

Требуются Docker Engine и Docker Compose. Это основной и рекомендуемый сценарий:

docker compose up --build

После успешного запуска:

Контейнер API сам выполняет alembic upgrade head, затем идемпотентный seed. PostgreSQL хранит данные в именованном volume postgres_data, а MinIO — в minio_data.

Остановка:

docker compose down

Удаление volume и повторное создание чистой базы — только когда данные больше не нужны:

docker compose down --volumes
docker compose up --build

Переменные и локальные значения по умолчанию перечислены в .env.example. Секретов в репозитории нет.

Что реализовано

  • FastAPI и SQLAlchemy 2;
  • PostgreSQL 17 и начальная миграция Alembic;
  • идемпотентный seed с двумя точками и свежими демо-уловами;
  • GET /api/v1/activity с фильтрами периода, водоёма, рыбы, способа и сортировки;
  • GET /api/v1/spots/{id} и /catches;
  • справочники рыб, водоёмов и приманок;
  • Astro SSR-интерфейс с адаптивным дизайном из design-reference без переноса React/Vinext-стека;
  • объяснимые индексы активности и уверенности по формуле спецификации;
  • состояния «нет данных» и «источник недоступен»;
  • идемпотентный импорт официальных записей с журналом запусков;
  • публичная страница /records с источником и временем последнего импорта;
  • форма /report, защищённые admin API и журнал модерации;
  • honeypot и базовый лимит отправок;
  • скриншоты уловов в MinIO/S3 с декодированием изображения, ограничением размера и очисткой метаданных.

Все пользовательские ники и уловы в seed демонстрационные.

Проверка проекта

Backend и исследовательский парсер:

python3 -m venv .venv
.venv/bin/pip install -r apps/api/requirements.txt
.venv/bin/pip install -e .
.venv/bin/pytest apps/api/tests tests -q

Frontend:

cd apps/web
npm install
npm run build
npm audit --omit=dev

E2E после запуска Compose:

cd apps/web
npx playwright install chromium
npm run test:e2e

Импорт официальных рекордов

Однократный контейнерный запуск после старта базы:

docker compose --profile tools run --rm importer

Импорт делает до трёх ограниченных попыток, проверяет DOM-контракт и не удаляет ранее сохранённые данные при сбое. Повторный запуск обновляет совпавшие записи по SHA-256 ключу и не создаёт дубликаты. Автоматическое расписание намеренно ещё не включено: сначала требуется согласовать допустимость регулярного опроса официального сайта.

Ручной административный запуск также доступен через POST /api/v1/admin/imports/official-records, журнал — через GET /api/v1/admin/imports. Импорт сохраняет HTTP-метаданные и использует ETag/Last-Modified, когда источник их предоставляет.

Планировщик реализован отдельным opt-in профилем и по умолчанию опрашивает источник не чаще одного раза в час:

docker compose --profile scheduler up -d scheduler

Обычный docker compose up его не запускает. Не включайте профиль во внешнем окружении, пока условия автоматического сбора не согласованы с владельцем источника; отсутствие robots.txt не является разрешением.

Пользовательские уловы и модерация

Новая запись из /report получает статус pending и не участвует в активности до одобрения. Административные методы требуют заголовок Authorization: Bearer $ADMIN_TOKEN:

curl -H "Authorization: Bearer change-me-in-production" \
  "http://localhost:8000/api/v1/admin/catch-reports?status=pending"

Перед внешним развёртыванием обязательно замените демонстрационный ADMIN_TOKEN, а также значения S3_ACCESS_KEY и S3_SECRET_KEY. Форма принимает JPEG, PNG и WebP до 8 МБ; API повторно кодирует изображение и удаляет EXIF перед сохранением в MinIO. Модератор получает временную подписанную ссылку через admin API.

Очередь модерации доступна по адресу http://localhost:4321/admin/moderation. Администратор вводит ADMIN_TOKEN; интерфейс держит его только в памяти открытой страницы и не сохраняет в URL или браузерном хранилище.

Исследовательский парсер официальных рекордов

python -m rf4_research.records \
  --url https://rf4game.de/records/region/RU/ \
  --region RU \
  --category records

Команда делает один HTTP-запрос и печатает типизированные записи в JSON. Это ещё не продуктивный импортёр: в нём нет повторов, кэша, транзакций и дедупликации. Подтверждённая структура источника и риски описаны в docs/data-sources.md.