# План работ RF4 Spotter Этот файл — рабочий источник правды по развитию проекта. После завершения задачи её чекбокс меняется с `[ ]` на `[x]`, рядом добавляется ссылка на коммит или короткое подтверждение проверки. Новые задачи добавляются в соответствующий этап, а не хранятся только в переписке. Обозначения: - `[x]` — выполнено и проверено; - `[ ]` — ещё не выполнено; - пункты выполняются сверху вниз, если явно не зафиксирована другая зависимость. ## Текущее состояние - [x] Этап 0: исследован официальный источник, добавлены парсер, фикстуры и `docs/data-sources.md` (`a6f91a1`). - [x] Этап 1: создан Docker-каркас Astro + FastAPI + PostgreSQL, миграции, seed, публичный API и базовый E2E (`d3a4524`). - [x] Основная часть этапа 2: адаптер официальных рекордов, нормализация, дедупликация, журнал импорта и страница рекордов (`d3a4524`). - [x] Основная часть этапа 3: форма пользовательского улова, модерация, rate limit, MinIO и безопасная обработка скриншотов (`6d536d0`, `c524272`). - [x] Визуальный референс перенесён в Astro без Next.js, Vinext и React (`c524272`). ## Этап 2 — завершить официальный импорт - [x] Добавить административный endpoint ручного запуска импорта `POST /api/v1/admin/imports/official-records` (проверено API-тестом). - [x] Привести журнал импорта к административному контракту `GET /api/v1/admin/imports` с авторизацией, пагинацией и стабильной сортировкой (проверено API-тестом). - [x] Добавить HTTP-кэширование источника (`ETag`/`Last-Modified`, если источник их отдаёт) и сохранить диагностические метаданные ответа (миграция `0005`, тест условного запроса и `304`). - [x] Добавить планировщик импорта с безопасной частотой по умолчанию один раз в 60 минут; отдельный контейнер/процесс без дублирования запусков (opt-in профиль `scheduler`, обычным запуском не активируется). - [x] Проверить актуальные `robots.txt` и условия использования перед включением расписания; результат записать в `docs/data-sources.md` (`robots.txt` вернул `404`; автоматический профиль оставлен выключенным до явного разрешения). - [x] Добавить интеграционные тесты: повторный импорт не создаёт дубликаты, сбой источника не удаляет данные, изменение DOM завершается понятной ошибкой. Критерий готовности: официальный импорт запускается вручную и по расписанию, наблюдаем, идемпотентен и безопасно переживает недоступность источника. ## Этап 3 — завершить пользовательские уловы - [x] Добавить административный веб-интерфейс очереди модерации поверх существующего API (`/admin/moderation`, токен только в памяти страницы). - [x] Показать скриншот, данные улова и причину решения; реализовать действия «одобрить» и «отклонить» (проверено в браузере на desktop и 390 px). - [x] Добавить удаление пользовательского сообщения администратором с аудитом действия (обезличивание записи, удаление объекта MinIO, миграция `0006`). - [x] Заменить in-memory rate limit на общее хранилище, пригодное для нескольких API-процессов и перезапусков (PostgreSQL, HMAC-отпечаток без хранения исходного IP, миграция `0007`). - [x] Валидировать одновременно содержимое, MIME, расширение и лимит изображения; добавить тесты каждого отказа. - [x] Добавить сквозной тест: отправка → pending → модерация → появление одобренного улова в публичной статистике (Compose/Playwright: `2 passed`). - [x] Добавить понятные состояния успеха и ошибок загрузки в форму, включая отдельную ошибку скриншота без потери уже созданной заявки (повторная загрузка по ID сохранённой заявки). Критерий готовности: полный пользовательский сценарий проходит через браузер, а модератору не нужен ручной вызов API. ## Этап 4 — индекс клёва - [x] Сверить текущую формулу активности и уверенности с разделом 11 спецификации и зафиксировать формулу в `docs/activity-index.md`. - [x] Покрыть unit-тестами затухание по свежести, доверие к официальным и пользовательским источникам, повторные сообщения одного игрока и вклад разных игроков. - [x] Не учитывать pending/rejected/удалённые записи и доказать это тестами. - [x] Добавить детерминированные агрегаты для окон 6, 12, 24 и 72 часа. - [x] На карточке и странице точки показывать человекочитаемое объяснение оценки и объём данных, на котором она основана (unit-тест объяснения и Astro build). - [x] Реализовать состояния «данных мало», «данных нет», «источник недоступен» и ошибки валидации фильтров (Astro build; браузерная проверка войдёт в общий прогон фильтров). - [x] Проверить фильтры главной страницы сквозным тестом на desktop и mobile (Playwright, 1280 px и 390 px). Критерий готовности: оценка объяснима, воспроизводима тестами и никогда не маскирует недостаток или устаревание данных. ## Подготовка MVP к пилоту - [ ] Добавить health/readiness-проверки PostgreSQL, MinIO, API и импорта; отразить их в Compose. - [ ] Добавить структурированные логи без пользовательских секретов и персональных технических данных. - [ ] Добавить резервное копирование и документированное восстановление PostgreSQL и MinIO. - [ ] Провести security-проверку admin-аутентификации, CORS, заголовков, загрузок и управления секретами. - [ ] Добавить CI: backend tests, Astro check/build, E2E и проверка миграций на чистой БД. - [ ] Проверить доступность интерфейса: клавиатура, focus states, контраст, подписи полей и семантика таблиц/карточек. - [ ] Провести Lighthouse-проверку основных страниц и устранить критические проблемы производительности. - [ ] Обновить README: архитектура, все переменные окружения, импорт, модерация, backup/restore и известные ограничения. - [ ] Выбрать лицензию кода и политику использования данных. - [ ] Заменить демонстрационные секреты и определить целевое размещение перед внешней публикацией. ## Источники данных и согласование - [x] Провести аудит подключённых источников, потенциальных поставщиков и всех существующих парсеров; результат записан в `docs/data-source-audit.md`. - [x] Проверить оба официальных HTML-парсера на актуальной странице и добавить общий контрактный тест эквивалентности. - [x] Добавить `data_source` и алиасы рыб/водоёмов до подключения второго автоматического источника (миграции `0008`–`0009`; алиасы приманок уже нормализуются в `bait`). - [x] Вынести общий официальный DOM-парсер, устранив дублирование исследовательской и продуктивной реализации (`rf4_research/official_parser.py`). - [x] Добавить отдельную фикстуру и безопасный ручной импорт недельных официальных рекордов одной категории. - [x] Получено подтверждение владельца проекта о разрешениях RF4DB и RF4-STAT; добавлены пилотные HTML-парсеры и отчёт `docs/community-source-pilot.md`. - [x] Добавлены общий nullable-контракт, парсер detail-страницы RF4DB и ограниченный read-only CLI для RF4DB/RF4-STAT. - [x] Зафиксировать проектное подтверждение разрешений, текущую атрибуцию и консервативные пилотные лимиты в `docs/data-permissions.md`; первичный документ и точные продуктивные условия ещё обязательны перед scheduler. - [x] Добавить staging-модель внешних наблюдений и идемпотентный импорт RF4DB/RF4-STAT без автоматического влияния на индекс (миграция `0008`, сквозной контрактный тест). - [x] Добавить административную очередь сопоставления staging-записей с каноническими рыбами/водоёмами и явную публикацию в `catch_report` (`/admin/external-sources`, миграция `0009`; неполные записи публиковать запрещено). - [ ] Согласовать один добровольный канал сообщества и правила происхождения, модерации и удаления сообщений. ## Этап 5 — пилот - [ ] Согласовать первые категории рекордов, водоёмы и виды рыб. - [ ] Наполнить базу небольшим разрешённым набором реальных данных. - [ ] Провести тестирование с несколькими игроками по подготовленному сценарию. - [ ] Собрать обратную связь по полезности точек, понятности уверенности, форме улова и мобильному интерфейсу. - [ ] Исправить блокирующие проблемы пилота и повторить проверку критериев MVP из раздела 16 спецификации. - [ ] Только после пилота принять решение по OCR, Telegram, профилям, уведомлениям и импорту сообществ. ## Ближайший рабочий пакет Лёгкий пакет по парсерам и фильтрам завершён. Следующий пакет готовит MVP к пилоту: 1. health/readiness PostgreSQL, MinIO, API и импорта; 2. структурированные логи без пользовательских секретов; 3. CI для тестов, Astro build, E2E и миграций; 4. backup/restore PostgreSQL и MinIO. После каждого пункта необходимо: 1. запустить затронутые unit/integration-тесты; 2. выполнить `docker compose up --build -d` и проверить health; 3. для UI-изменений проверить desktop и ширину 390 px; 4. обновить чекбокс в этом файле; 5. зафиксировать результат отдельным небольшим коммитом.