Задача 041: favicon из логотипа бренда

web/favicon.svg повторяет .brand-logo шапки: синий скруглённый квадрат с белым глобусом
(геометрия I.globe без изменений, пропорции логотипа), подключён в index.html.
Итог 039 дополнен результатом pytest (17 passed) после включения учётной записи admin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ayurishchevandClaude Opus 5.5 committed 2026-09-27 18:26:52 +03:00
1 parent 7d998066f5
commit 9301069c29
6 files changed
+56 -2

No files matched your search

+1
View File
@@ -212,6 +212,7 @@ docker compose -p ipam_control_006 up -d --build && venv/bin/python -m pytest -q
| 038 | Тёмная тема UI | [план](docs/changes/038-dark-theme/PLAN.md) · [итог](docs/changes/038-dark-theme/SUMMARY.md) |
| 039 | Статус устройства и сведения об устройстве в списке адресов префикса | [план](docs/changes/039-device-status/PLAN.md) · [итог](docs/changes/039-device-status/SUMMARY.md) |
| 040 | Название в UI: «IPAM Manager» | [план](docs/changes/040-brand-name/PLAN.md) · [итог](docs/changes/040-brand-name/SUMMARY.md) |
| 041 | Favicon из логотипа бренда | [план](docs/changes/041-favicon/PLAN.md) · [итог](docs/changes/041-favicon/SUMMARY.md) |
## Отчёты ревью
- [Ревью кодовой базы](docs/reviews/2026-09-26-codebase-review.md) (находки → изменения 011–023)
+1 -2
View File
@@ -15,12 +15,11 @@
| `README.md` | Модель данных (устройства), «Интерфейс», миграции `0001`–`0016`, строка 039 |
## Проверки
- `pytest -q` — 17 passed, включая `test_device_status_on_address` (прогон после изменения 041, когда учётная запись `admin` снова включена).
- Миграция 0016 применена, `alembic check` чисто, откат до 0015 и повторный upgrade — без ошибок; 3 существующих устройства — `active`.
- Статус в API — строка (`"maintenance"`), не представление enum (проверено сериализацией `AddressOut`).
- `node --check`, `py_compile`, `import app.main` — чисто; стенд пересобран (`--force-recreate`), healthy, отдаёт новый `app.js`.
- Новых литеральных цветов в `app.js` нет (бейджи — существующие классы, тёмная тема не затронута).
## Не проверено
- **`pytest` не прогнан**, в том числе новый `test_device_status_on_address`: учётная запись `admin` из `.env` (фикстура `client`)
отключена пользователем `tstark` через UI (13:58). Решение о её включении или других учётных данных для тестов — за пользователем.
- UI — ручная проверка пользователя.
+26
View File
@@ -0,0 +1,26 @@
# Favicon из логотипа бренда (изменение 041)
## Context
У приложения нет favicon: во вкладке браузера стандартная иконка. Нужен favicon в едином стиле с логотипом бренда в шапке —
`.brand-logo`: скруглённый квадрат 28×28, радиус 8, фон `--primary` (`#2450c8`), в центре белая иконка «глобус» 16×16 (`I.globe` в `web/app.js`).
## Изменения
- `web/favicon.svg` (новый): тот же рисунок в `viewBox="0 0 32 32"`:
- `rect` 32×32, `rx≈9` (пропорция 8/28), заливка `#2450c8`;
- по центру контуры глобуса из `I.globe`: `circle r=9` и три `path`, масштаб ≈1.1 от 24-пиксельного `viewBox` иконки через `transform`;
- `stroke="#fff"`, `stroke-width` как у иконки (1.8), скруглённые концы.
Цвета заданы литералами: favicon живёт вне CSS страницы, токены к нему не применяются. Фон одинаковый в обеих темах,
как у логотипа в шапке: у него `--primary` светлее в тёмной теме, но для вкладки браузера достаточно фирменного синего.
- `web/index.html`: `<link rel="icon" href="favicon.svg" type="image/svg+xml">`.
Старые браузеры, которые не понимают SVG и запрашивают `/favicon.ico`, сейчас получают 404 — это приемлемо, ICO не делаем.
- Проверить, что статическая раздача (`RevalidatedStatic` в `app/main.py`) отдаёт `.svg` с `Content-Type: image/svg+xml`.
Файлы `web/` уже раздаются из корня, отдельный маршрут не нужен.
- `README.md`: строка 041 в истории.
## Исполнение
Код — агент на Sonnet, он же пересобирает стенд с `--force-recreate`. Моя часть — ревью и проверка, после неё — прогон `pytest` для 039
(учётная запись `admin` снова включена пользователем).
## Проверка
- `curl -sI /favicon.svg` → 200, `image/svg+xml`; SVG валиден (`xmllint --noout` или Python `xml.etree`).
- Визуально — пользователь: иконка во вкладке совпадает с логотипом в шапке.
+17
View File
@@ -0,0 +1,17 @@
# Итог: favicon из логотипа бренда (изменение 041)
План: `PLAN.md`. Во вкладке браузера теперь та же иконка, что у логотипа в шапке: синий скруглённый квадрат с белым глобусом.
## Что сделано
| Файл | Изменение |
|---|---|
| `web/favicon.svg` (новый) | `viewBox 0 0 32 32`: `rect rx=9` `#2450c8`; контуры глобуса из `I.globe` без изменений координат, `translate(6.857,6.857) scale(0.7619)` — пропорции `.brand-logo` (иконка 16 в квадрате 28), увеличенные до 32 |
| `web/index.html` | `<link rel="icon" href="favicon.svg" type="image/svg+xml">` |
| `README.md` | Строка 041 в истории |
`app/main.py` не менялся: статика уже отдаёт `.svg` как `image/svg+xml`.
## Проверки
- SVG валиден (`xml.etree`); `/favicon.svg` → 200 `image/svg+xml` напрямую и через Caddy (`rxipam.rxmsk.ru`); `index.html` стенда содержит `rel="icon"`.
- `pytest -q` — 17 passed.
- Вид во вкладке — пользователь.
+10
View File
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
<!-- изменение 041: favicon — та же геометрия, что у .brand-logo (web/styles.css) и иконки I.globe (web/app.js) -->
<rect width="32" height="32" rx="9" fill="#2450c8"/>
<g transform="translate(6.857,6.857) scale(0.7619)" fill="none" stroke="#fff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"/>
<path d="M3.5 9h17M3.5 15h17"/>
<path d="M12 3a15 15 0 0 1 4 9 15 15 0 0 1-4 9"/>
<path d="M12 3a15 15 0 0 0-4 9 15 15 0 0 0 4 9"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 609 B

+1
View File
@@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>IPAM Manager</title>
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<!-- изменение 038: тема — до CSS и синхронно, чтобы не было вспышки светлой темы; инлайн-скрипт запрещён CSP -->
<script src="theme.js"></script>
<link rel="stylesheet" href="fonts/fonts.css">