Compare commits

..
2 Commits
Author SHA1 Message Date
ik 6e21bb774d perf: optimize public image assets
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
2026-09-08 16:18:32 +07:00
ik 18855644a4 build: separate API development dependencies 2026-09-08 16:16:09 +07:00
9 changed files with 10 additions and 6 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -r apps/api/requirements.txt
pip install -r apps/api/requirements-dev.txt
pip install -e .
- name: Apply migrations to clean PostgreSQL
working-directory: apps/api
+4 -2
View File
@@ -159,13 +159,15 @@ Backend и исследовательский парсер:
```bash
python3 -m venv .venv
.venv/bin/pip install -r apps/api/requirements.txt
.venv/bin/pip install -r apps/api/requirements-dev.txt
.venv/bin/pip install -e .
.venv/bin/pytest -q
```
Актуальное число тестов выводит команда `pytest`; набор включает backend, импорт, расчёт активности и исследовательский парсер.
Production-образ API устанавливает только `requirements.txt`; `pytest` подключается отдельно через `requirements-dev.txt` в локальной среде и CI.
Frontend:
```bash
@@ -237,7 +239,7 @@ Production-логи структурированы в JSON и не содерж
- нет пользовательских аккаунтов, OCR, Telegram-бота и уведомлений о клёве;
- community-источники автоматически публикуют только полные наблюдения с подтверждёнными алиасами; новые соответствия требуют ручной проверки, неполные наблюдения не публикуются;
- offset pagination рассчитана на пилотные объёмы, не на бесконечную ленту;
- Lighthouse LCP локального прогона — 9,3 с; оптимизация изображения/CDN остаётся после размещения;
- прежний локальный Lighthouse показывал LCP 9,3 с; после него hero уменьшен с 1,6 МБ до 71 КБ и получил высокий приоритет загрузки, повторный production-замер выполняется после размещения;
- один сервер остаётся точкой отказа, поэтому обязательны внешний backup и мониторинг;
- текущий публичный DNS/TLS не подтверждён, см. [статус развёртывания](docs/deployment-status.md).
+2
View File
@@ -0,0 +1,2 @@
-r requirements.txt
pytest==8.4.2
-1
View File
@@ -7,6 +7,5 @@ psycopg[binary]==3.2.10
pydantic-settings==2.10.1
pillow==11.3.0
python-multipart==0.0.20
pytest==8.4.2
sqlalchemy==2.0.43
uvicorn[standard]==0.35.0
Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

+1 -1
View File
@@ -45,7 +45,7 @@ const datasetJsonLd = {
};
---
<Layout title="Что клюёт сейчас в Russian Fishing 4 — RF4 Spotter" description="Свежие точки клёва RF4, рабочие приманки, вес уловов и прозрачная оценка данных с указанием каждого источника." structuredData={datasetJsonLd}>
<section class="intro content-grid"><div class="intro-copy"><span class="eyebrow"><b>RF4</b> Живая карта клёва</span><h1>Выбирай место,<br/><em>пока клюёт.</em></h1><p>Свежие точки, рабочие приманки и честная оценка данных от игроков.</p></div><div class="lake-card"><img src="/lake-dawn.png" alt="Туманное озеро на рассвете"/><div class="lake-overlay"><div><span class="overline">Пульс водоёмов</span><strong>{items.length} {plural(items.length, ["точка показывает", "точки показывают", "точек показывают"])} активность</strong></div><div class="pulse-orb"><span></span></div></div></div></section>
<section class="intro content-grid"><div class="intro-copy"><span class="eyebrow"><b>RF4</b> Живая карта клёва</span><h1>Выбирай место,<br/><em>пока клюёт.</em></h1><p>Свежие точки, рабочие приманки и честная оценка данных от игроков.</p></div><div class="lake-card"><img src="/lake-dawn.webp" alt="Туманное озеро на рассвете" width="1774" height="887" fetchpriority="high"/><div class="lake-overlay"><div><span class="overline">Пульс водоёмов</span><strong>{items.length} {plural(items.length, ["точка показывает", "точки показывают", "точек показывают"])} активность</strong></div><div class="pulse-orb"><span></span></div></div></div></section>
<section class="filters-wrap"><form class="filters content-grid" method="get" action="/#results">
<label>Водоём<select name="waterbody"><option value="">Все водоёмы</option>{waterbodies.map(x => <option value={x.slug} selected={waterbody === x.slug}>{x.name_ru}</option>)}</select></label>
<label>Рыба<select name="fish"><option value="">Любая рыба</option>{fishes.map(x => <option value={x.slug} selected={fish === x.slug}>{x.name_ru}</option>)}</select></label>
+2 -1
View File
@@ -26,7 +26,8 @@
- [x] Sitemap постоянных страниц с пагинацией, без ограничения активности 72 часами. Последняя успешная версия хранится в памяти процесса; после перезапуска при недоступном API возвращается 503.
- [x] Подключить API подсказок алиасов к административному UI: кнопка показывает подтверждённые русские названия; выбор и сохранение остаются отдельными действиями.
- [x] Web Dockerfile использует npm ci; инструменты проверки/тестирования перенесены в devDependencies и удаляются перед копированием runtime. Обновлён lock-файл без сети. Сборка Docker-образа остаётся проверкой перед деплоем.
- [ ] Оптимизировать изображения и Python production-зависимости.
- [x] Удалить pytest из Python production-зависимостей; локальная среда и CI используют отдельный requirements-dev.txt (8 сентября 2026).
- [x] Hero переведён в WebP (1,6 МБ → 71 КБ), PNG-иконка переупакована (368 КБ → 69 КБ), изображения получили явные размеры и приоритет LCP. Pillow нужен в runtime: API декодирует и повторно кодирует пользовательские изображения для проверки формата, удаления EXIF и безопасного хранения.
- [ ] Визуальная проверка 320/390/768/1280 px, исправление карточек и пустых состояний.
- [ ] Согласовать остальные формулировки README/roadmap с фактическим поведением.