# RF4 Spotter RF4 Spotter — неофициальный сервис свежих точек и статистики клёва для Russian Fishing 4. Этап 1 содержит контейнерный каркас, демоданные, read-only API, главную страницу и страницу точки. Реальный импорт официальных рекордов пока остаётся отдельным исследовательским адаптером этапа 0. ## Запуск через Docker Требуются Docker Engine и Docker Compose. Это основной и рекомендуемый сценарий: ```bash docker compose up --build ``` После успешного запуска: - сайт: ; - OpenAPI: ; - проверка API: ; - консоль MinIO: . Контейнер API сам выполняет `alembic upgrade head`, затем идемпотентный seed. PostgreSQL хранит данные в именованном volume `postgres_data`, а MinIO — в `minio_data`. Остановка: ```bash docker compose down ``` Удаление volume и повторное создание чистой базы — только когда данные больше не нужны: ```bash docker compose down --volumes docker compose up --build ``` Переменные и локальные значения по умолчанию перечислены в [.env.example](.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 и исследовательский парсер: ```bash 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: ```bash cd apps/web npm install npm run build npm audit --omit=dev ``` E2E после запуска Compose: ```bash cd apps/web npx playwright install chromium npm run test:e2e ``` ## Импорт официальных рекордов Однократный контейнерный запуск после старта базы: ```bash 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 профилем и по умолчанию опрашивает источник не чаще одного раза в час: ```bash docker compose --profile scheduler up -d scheduler ``` Обычный `docker compose up` его не запускает. Не включайте профиль во внешнем окружении, пока условия автоматического сбора не согласованы с владельцем источника; отсутствие `robots.txt` не является разрешением. ## Пользовательские уловы и модерация Новая запись из `/report` получает статус `pending` и не участвует в активности до одобрения. Административные методы требуют заголовок `Authorization: Bearer $ADMIN_TOKEN`: ```bash 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. ## Исследовательский парсер официальных рекордов ```bash python -m rf4_research.records \ --url https://rf4game.de/records/region/RU/ \ --region RU \ --category records ``` Команда делает один HTTP-запрос и печатает типизированные записи в JSON. Это ещё не продуктивный импортёр: в нём нет повторов, кэша, транзакций и дедупликации. Подтверждённая структура источника и риски описаны в [docs/data-sources.md](docs/data-sources.md).