All notable changes to BirdLense Hub are documented in this file.
The format is based on Keep a Changelog.
-
A2 / roadmap #418: переменная
BIRDLENSE_HIDE_DIRECT_RECORDINGS(1/true/yes/on) — при старте контейнера не добавляется nginx-locationдля/data/recordings/; анонимный доступ к предсказуемым URL получает 403, воспроизведение остаётся через/api/ui/videos/:id/stream(app/nginx/standalone.conf.template,app/scripts/entrypoint.sh). Доки: CONFIGURATION, SECURITY, DEPLOY_SERVER (EN/RU),app/.env.example. Публичный VPS — единый чеклист:docs/PUBLIC_RECORDINGS*.md(#423). -
#341: на POST upload-роутах (веса процессора, file-test, restore SQLite, YAML import) отклоняется непустой
Content-Encoding, кроме единственного значенияidentity— снижает риск decompression bomb при нетипичных клиентах (services/upload_request_encoding_guard.py). Путь из ревьюprocessor.js/uploads.jsв этом репозитории отсутствует; дублирующих Flask-логгеров по коду не найдено. -
#339: nginx больше не отдаёт весь volume
DATA_DIRпо префиксу/data/. Разрешены только/data/recordings/,/data/images/,/data/file_test/(видео, картинки каталога, file-replay); остальное, включая/data/db/*.db, датасет и кэш, получает 403 (app/nginx/standalone.conf.template,standalone.conf,default.conf).
-
Roadmap EN/RU: секция Scale / #424 — статус закрытого эпика и таблица результатов B1–B3 (ссылки на доки и #432–#434).
-
Scale #432: процессор — наблюдаемость
triggers.*: gauge вprocessor_runtime_stats.json(trigger_cfg_*,trigger_mqtt_*,trigger_frigate_degraded_no_mqtt,trigger_*_paths_count, …), счётчики fallback фабрики motion (trigger_motion_factory_*), обновление при старте motion-стека и connect/disconnect MQTT (trigger_runtime_gauges.py,motion_runtime.py,mqtt_aggregator.py,motion_detectors/factory.py). -
Scale #433: документация — очереди/backpressure (
mqtt.publish_queue_max,mqtt_outbound_*,motion_trigger_queue_drop_total,feeder_scale_queue_drops_total) в PROCESSOR_PERFORMANCE EN/RU, CONFIGURATION EN/RU (ключpublish_queue_max), TROUBLESHOOTING EN/RU. -
Scale #434 / epic #424: операторский SSOT для PostgreSQL как БД хаба —
archive/internal/docs-legacy/POSTGRES_MIGRATION.md/.ru.md(compose,DATABASE_URL, пул, greenfield vs миграция данных, ограничения процессорского SQLite и BirdNET FIFO); навигация MkDocs, SITE_MAP EN/RU, строки в CONFIGURATION EN/RU, блок в RUNBOOKS EN/RU. -
A2 / roadmap #423: единый операторский SSOT для публичного контура записей —
docs/user/public-recordings.md/.ru.md; SECURITY / DEPLOY_SERVER / CONFIGURATION / ACCESS_CONTROL сведены к перекрёстным ссылкам вместо дублирования чеклистов; mkdocs, SITE_MAP, README (EN/RU). -
Деплой (доки): явно зафиксирован сценарий только
http://IP:портбез домена и без внешнего reverse proxy до появления DNS/TLS —DEPLOY_SERVER(EN/RU),deploy.local.sh.example,.cursor/rules/deploy.mdc, подсказка в концеscripts/deploy.sh. -
A1 / деплой: опционально
RUN_VERIFY_PROD_BEFORE_DEPLOY=1вdeploy.local.sh— перед rsync вызываетсяscripts/verify-prod-env.shпо локальной копии serverapp/.env; цельmake preflight-deploy(=verify-prod-env+make verify). Пример базового URL VPS вDEPLOY_SERVER(EN/RU). -
A3 / наблюдаемость CV: в JSON-строке
recording_session_summary(processor logs) добавлены поляduration_s,triggered_camera,yolo_frames_with_tracks,session_extended_by_frigate_only— проще root-cause по воронке; TROUBLESHOOTING EN/RU обновлены. -
Триггеры и конфиг: из
default_config.yamlубран блокmotion:; источник истины для захвата —triggers.*. Остатокmotion:в пользовательском YAML при загрузке сворачивается вtriggers(migrate_legacy_motion_block,fold_legacy_motion_out_of_merged_config).get_effective_trigger_configбез чтенияmotion.*как fallback; нужен явныйtriggers.frigate.enabledдля записи по Frigate. UI: фильтры Frigate вtriggers.frigate.*. Документы ARCHITECTURE, CONFIGURATION (EN/RU), TESTING/TROUBLESHOOTING/GLOSSARY (EN/RU), CONFIGURATION_TRIGGERS_INVENTORY (EN/RU), SETTINGS_TRIGGERS_PHASE2 (EN/RU) приведены в соответствие. -
Документация: актуализация ROADMAP EN/RU — секция Scale / #424 (треки B1–B3: motion/triggers, очередь процессора, Postgres); дочерние issues #432–#434; родитель фазы #418. Ранее в этом блоке: апрель 2026 в заголовках backlog, UI видов v0.3.7+, outcome эпика реестра; SECURITY EN/RU (baseline gitleaks); индекс docs/README / README.ru и эпик CV/ML #367, CV_ML_PREP / RU, HUB_EPICS_TRACKER / RU; VERIFICATION / RU.
-
#343 (фазы C–D): UI —
BirdFoodи ответы/status,/readinessтипизированы черезopenapi-types(types.ts,camerasHealth.ts); документdocs/project/UI_API_MANUAL_CONTRACTS.md(ручные контракты: камеры, feed/info, observability) + ссылка изdocs/project/openapi.md; Vitest:client.test.ts,camerasHealth.test.ts,birdFoodFeed.test.ts;data-testidна пунктах навигации (nav-pill-*,nav-live, мобильноеnav-mobile-*) и смоук Playwright наnav-pill-timeline. -
#343 (фаза B): UI — импорты страниц/хуков/настроек переведены с барреля
api.tsxна доменные модули (client,timeline,video,weatherRegion,migrationCalendar,dataset,birdFoodFeed,camerasHealth,fileTest,settingsSession,settingsYamlDb,systemAuditMetrics,notificationsProcessor,speciesRegistryHub,speciesOverviewDetections); вapi.tsxостаютсяgetApiErrorMessage,resolveImageUrlи реэкспорты; обновлены моки Vitest (SpeciesDirectory,RecognitionImprovement,TimelinePage,Navigation,App.routes). -
#343 (фаза A): UI —
client.ts(base URL, axios timeout,JOB_STATUS_POLL_TIMEOUT_MS),timeline.ts,video.ts(видео, соседи, fusion trace, nearest recording day, delete/regen/merge),weatherRegion.ts,migrationCalendar.ts,dataset.ts,birdFoodFeed.ts,camerasHealth.ts,fileTest.ts,settingsSession.ts,systemAuditMetrics.ts,notificationsProcessor.ts(push / notify / restart / веса),settingsYamlDb.ts(YAML, БД, purge, ZIP→координаты),speciesRegistryHub.ts(реестр, fusion/recognition, BirdNET FIFO, purge-диагностика),speciesOverviewDetections.ts(каталог/обзор вида, тюнинг, Xeno-Canto, PDF, детекции, review-queue, corrections);api.tsx—getApiErrorMessage,resolveImageUrlи реэкспорты;queryKeys— таймлайн, unknowns, video, bird-directory, speciesSummary (в т.ч.bySpecies), storage (stats), overview / weather / calendar,systemPanels(аудит конфига, observability, каталог, recognition/fusion, веса и др.), feed, health (статус шапки), live (камеры), birdFood, fileTest, speciesDirectory; миграция ключей на Timeline, Unknowns, VideoDetails / VideoInfo / DetectedSpecies, Overview, WeatherCard, MigrationCalendar, DatabaseMaintenanceCard, StorageOverview, RecordingsCalendar, DatasetExportsCard, Navigation, FeedCard, StatusIndicator, Footer, Live, FoodManagement, FileReplayCard, карточки Система (SystemHero, ConfigAudit, Observability, CatalogRepair, RecognitionImprovement, SpeciesDataQuality, ClassifierDatasetAlignment, ProcessorWeights, AutomationFusion), SpeciesDirectory, SpeciesSummary, ProcessorFrigateFusionBlock; тестыtimeline.test.ts,video.test.ts,weatherRegion.test.ts. -
Документация (CONFIGURATION): EN/RU — блок On this page / По странице (быстрые якоря), ссылки на
app/.env.exampleиdocs/project/openapi.mdв шапке; I18N_STATUS — строка SETTINGS_TRIGGERS_PHASE2, шаг про OpenAPI/contract-тест при смене HTTP-маршрутов. -
Документация (рефакторинг): в README EN/RU — одна строка для CI-политики вместо дублирующихся ссылок на CI_AND_QUALITY; в блоке безопасности EN — ссылка на SECURITY.ru; в README.ru — симметричные EN-ссылки для ACCESS/SECURITY; в таблицах команд — регенерация OpenAPI. В Documentation EN/RU — раздел OpenAPI spec maintenance с якорем
{#openapi-spec-maintenance}, пункт чеклиста ревью и строка в Key documents; SITE_MAP EN/RU — строка про скрипты OpenAPI. -
Документация: описание CI приведено к текущим workflow (ежедневный прогон
ci-pr.ymlна ветке по умолчанию,workflow_dispatch; E2E (Playwright) — ежедневно, не «раз в неделю»). Задокументированыmake ci-local/make ci-local-dockerи скриптscripts/ci-full-local.sh(README EN/RU,docs/CI_AND_QUALITY*,docs/TESTING*,docs/LOCAL_DEV*,docs/QUICKSTART,docs/README*,docs/Documentation*,docs/REPOSITORY_LAYOUT*,docs/VERIFICATION*,docs/OVERVIEW*). В README.ru в таблицу команд добавлен отсутствовавшийmake verify. -
Документация (установка/деплой):
docs/INSTALL*,docs/DEPLOY_SERVER*— выравнивание сscripts/deploy.sh: локальная сборка UI до rsync,DEPLOY_SSH_PORT, не удаляетсяbirdlense-redis, полныйverify-stack, список исключений rsync (в т.ч..venv-ci). Вариант 4: явно про Redis в полномdocker-compose.ymlvs минимальный image compose. В INSTALL.ru добавлены шагиmake verifyдля вариантов 2–3. -
Деплой: в
scripts/deploy.shrsync-исключение.venv-ci, чтобы локальный CI-venv не уезжал на сервер. -
Документация (продолжение): исправлен несуществующий
make restart→docker compose restart birdlense/make stop && make start(TROUBLESHOOTING, RECOVERY_CONFIG.ru). ARCHITECTURE EN/RU — пояснение портов nginx/Flask/MCP. SCENARIOS 6 — ссылки на DEPLOY_SERVER иmake verify. FEATURES EN/RU — строка Library и примерGET /readinessв таблице маршрутов. API EN/RU — строка/readiness. GLOSSARY EN/RU — термины Library / Библиотека. MCP_SETUP EN/RU — явная ссылка наscripts/deploy.sh. -
Документация (аудит): в SECURITY / SECRETS_ROTATION EN/RU везде явно
app/.envтам, где речь о сервере/контейнере; RECOVERY_CONFIG EN — явные команды перезапуска после ручного копирования YAML. SETTINGS_TRIGGERS_PHASE2 включён вmkdocs.ymlи SITE_MAP (EN/RU), чтобыmkdocs build --strictне ругался на страницу внеnav. -
Документация (CONFIGURATION): таблица переменных окружения EN/RU выровнена с
app/.env.example:FLASK_MAX_CONTENT_LENGTH,GUNICORN_THREADS,TRUSTED_PROXY,HA_URL,XENO_CANTO_API_KEY,HF_TOKEN, сэмплер системных метрик,BIRDLENSE_METRICS_TOKEN; исправлен смешанный RU-текст в английской таблице; якоря{#prometheus--grafana}/{#system-page-metrics-history}для внутренних ссылок. -
OpenAPI / API docs: в
app/web/openapi.yamlописаны все маршруты/api/ui/system/species-registry/*(seed, backfill, unresolved, enrich-metadata, health, materialize-allowlist, repair-cards, data-quality, classifier-dataset-alignment, coverage-metrics, tuning-targets/export); вdocs/contributor/api.md/docs/ru/api.ru.md— таблица-обзор с отсылкой к YAML. -
OpenAPI (полное покрытие UI + processor): второй
serversURL…/api/processorи пути ingest; для/api/uiдобавлены недостающие маршруты (cameras, status/debug, push, feed, video download/stream/delete/merge/regen, settings unlock/yaml, notify, species extras, timeline/report exports, dataset/detections, storage nearest-day, domain-health, fusion jobs, telegram-proxy refresh, diagnostics, review-queue, DB backup/restore, retention, observability, visitors/track и др.) плюсDELETE /videos/{video_id}. Скриптыscripts/generate_openapi_remaining_paths.pyиscripts/merge_openapi_fragments.pyдля регенерации блока;docs/project/openapi.md— как пользоваться двумя серверами в спецификации. -
Настройки (UI): удалён неиспользуемый
VideoSection(дублировал захват/кормушку и старую модельmotion.source). Поля весов интеграции и кормушки вынесены вshared/scalesIntegrationFields.tsxиshared/feederRelayFields.tsx. Вcheck-settings-ui-coverage.pyдля legacyintegrations.scales.motion_trigger_*добавлен явный allowlist (смена наtriggers.scales.*в форме). -
Процессор в настройках:
ProcessorSection.tsxразбит на восемь блоков вsections/processor/*.tsx(пороги, тайминги, мультикамера/BirdNET, расширенные пороги, guardrails, light gate, спектрограмма/датасет, Frigate fusion) — оркестратор ~70 строк. -
Coverage настроек: из
AUTO_ALLOWLIST_KEYSубраны ключи, для которых уже естьform.Fieldв дереве Settings (меньше ложного «planned-ui» для полей с UI). -
#340: тесты
processor_runtime_statsдля больших байтовых gauge (порядка 100 GiB), окна latency сmaxlen=200и отрицательных сэмплов; в миграции004_birdnet_fifo_eventуточнено, чтоsa.JSON()на PostgreSQL создаётся как JSONB (SQLAlchemy 2.x).
0.3.7 - 2026-04-25
- Версия проекта 0.3.7 (
VERSION, OpenAPI, MkDocssite_version, UIpackage.json).
0.3.6 - 2026-04-21
- Версия проекта 0.3.6 (
VERSION, OpenAPI, MkDocssite_version, UIpackage.json).
0.3.5 - 2026-04-15
- Версия проекта 0.3.5 (
VERSION, OpenAPI, MkDocssite_version, UIpackage.json).
- Трассировка fusion:
GET /api/ui/videos/{id}/fusion-traceи кнопка на странице ролика — только для оператора (contributor) и администратора (contributor_or_admin_access), не для анонимных зрителей. OpenAPI и CONFIGURATION (EN/RU) обновлены.
-
Единый контракт verify / readiness:
scripts/verify-stack.sh— последовательная проверка/api/ui/health,/api/ui/readiness(200 или 503 с полезной нагрузкой),/api/ui/status(опционально камеры); подключено вinstall.sh,scripts/deploy.sh,make verify(корень иapp/).GET /api/ui/readiness— пинг БД, проверка записи вdata/иapp_config/, компоненты в JSON; в строгом UI API добавлен allowlist для readiness/status. Карточка Система → готовность (SystemReadinessCard), axiosvalidateStatusдля 200/503. OpenAPI:/readiness, расширенная схема 503. Vitest (app/ui/:npm run test) в CI; E2E smoke — ожидание health и навигация. Документация:docs/user/quickstart.md,docs/user/runbooks.md, обновления README, INSTALL, LOCAL_DEV, DEPLOY_SERVER, TESTING, VERIFICATION,mkdocs.yml. -
Свои веса YOLO из UI (#276): Система → Веса процессора — загрузка
.ptдля бинарного детектора и классификатора иclass_names.txtвDATA_DIR/custom_weights/, обновлениеuser_configабсолютными путями, сброс к встроенным путям, флаг перезапуска процессора после операций. APIGET/POST /api/ui/system/processor-weights/*; проверка.ptкак zip-чекпойнта безtorchв web; загрузка классификатора требует существующего allowlist илиacknowledge_classifier_only. -
Тестовый прогон по файлам без рестарта (#270): при
video.source=fileпроцессор не блокируется на пустой папке; обмен черезdata/file_test_control/desired.jsonиstatus.json(старт/стоп, loop, abort сессии). APIGET/POST /api/ui/system/file-test/*, карточка на странице Библиотека (список, upload, удаление, прогресс polling).GET .../statusвсегда 200 с полемvideo_source, чтобы UI не опрашивал 409 вне режимаfile. -
Fusion decision trace (#272):
GET /api/ui/videos/{id}/fusion-traceи диалог на странице ролика (Fusion trace / Трассировка fusion) — шаги по трекам (детектор → классификатор → evidence → аудио → fusion → итог) плюс сырой JSON; документация в CONFIGURATION (EN/RU). -
BirdNET MQTT FIFO (#269): таблица
birdnet_fifo_eventв hub БД (Alembic004_birdnet_fifo_event); процессор пишет в SQLitedata/db/birdlense.dbчерез фоновый поток (WAL,busy_timeout), гидратирует RAM при старте MQTT;GET .../diagnostics/birdnet-fifoотдаёт снимок из БД при наличии строк (иначе JSON-файл как раньше). Ключиprocessor.birdnet_fifo_persist_enabled,processor.birdnet_fifo_sqlite_busy_ms. ПриDATABASE_URLPostgreSQL запись из процессора отключена (нет общего sqlite-файла). -
BirdNET FIFO — диагностика в UI (#303): диалог Система → Автоматизация → BirdNET FIFO — таблица видов (
species_fifo_table: MQTT-имя, ключ слияния с видео, счётчик событий, латинское имя, «как давно»), зелёная полоса слева для «услышан в окне»; сырой JSON в свёрнутом блоке; общий merge-key (app_config/birdnet_merge_key) для web и processor; тесты web/processor; локали EN/RU. Закрывает UX по сравнению с «стеной JSON».
-
Web / observability: заголовок
X-Request-IDи логирование с привязкой к запросу (app/web/app_logging.py, подключение изapp.py). -
Deploy script:
scripts/deploy.sh—set -euo pipefail, локальноnpm ci && npm run buildвapp/ui, пост-деплой проверка черезverify-stack.sh; безопасная подстановка необязательных переменных окружения в remote heredoc (${VAR:-}). -
Документация (тон и структура): MCP описан как протокол для авторизованных клиентов (автоматизация, интеграции), без акцента на ИИ-редакторы; README / OVERVIEW / SHORT_DESCRIPTION — явная аудитория орнитология и citizen science; внутренние файлы
PRE_IMPLEMENTATION_UNKNOWN_TIMELINE*.mdиLEGACY_CLEANUP.mdисключены из публикуемого MkDocs; навигация и перекрёстные ссылки подогнаны подmkdocs build --strict. -
UI / CI: job
ui-buildзапускаетnpm run typecheck(tsc -p tsconfig.app.json); типSettingsрасширен полями процессора / весов / motion из конфига; мелкие правки под строгий TS (Pie highlightScope, PWA virtual module, web-pushpatchSettings).locales/zh.json— полное дерево ключей как вen.json, перевод на упрощённый китайский (zh-CN); пилотная локальdeудалена, сохранённый языкdeв localStorage однократно переносится наzh. -
Офлайн-прогон по файлам (UI): заголовок секции и единственный переключатель зацикливания — только внутри карточки на Библиотеке; якорь
#file-replayна самой карточке. Документация RU: исправлена ссылка «Система» → Библиотека. Лимит uploadvideo.file_test_max_upload_mb: по умолчанию 10240 MiB (>10000), зажим в коде 64–65536 MiB. -
Fusion decision trace (семантика): в payload
decision_traceдобавленыpersisted_tracks/persisted_track_countи флаг строкиpersisted_to_clip;accepted_tracksостаётся ссылкой на тот же список (legacy). Экспорт fusion-training и скрипт CSV обходят один список клипа, чтобы не дублировать строки. UI/API: bucket трекаpersisted, подписи «сохранено в клипе» vs «DecisionMaker accepted». -
BirdNET ↔ видео, ключ слияния: в
birdnet_merge_keyсначала матчитсяdetection.species_mappingпо научному имени (ключи видаParus major (Great Tit)), затем ужеspecies_taxon.common_nameиз SQLite — колонка «ключ для видео» и слияние с YOLO не прыгают между русским и английским из‑за локали в каталоге. Вdefault_config.yamlдобавлены типовые европейские виды (в т.ч. из RU BirdNET). -
species_normalizer._to_title_case: дефисы в составе названия не превращаются в пробелы (корректнее вывод дляRed-breasted Flycatcher,Eurasian Eagle-Owlи т.п. послеnormalize()). -
birdnet_merge_key: значение изdetection.species_mappingпо научному имени возвращается как в YAML (без повторногоnormalize()), чтобы не портить написание вроде Red-breasted / Eagle-Owl.
-
Intel GPU на сервере (VA-API + метрики UI):
docker-compose.overrideтеперь генерируется скриптомapp/scripts/docker-compose-intel-override-gen.sh: все/dev/dri/renderD*иcard*,group_addс GID групп video/render хоста (раньше без них устройства былиrw-rw----→ VA-API и косвенно метрики ломались),CAP_PERFMONвместе сSYS_ADMINдляintel_gpu_top. Вызывается изscripts/deploy.shи из GitHub Actions Deploy передmake start. -
Intel PMU /
intel_gpu_topна VPS: приkernel.perf_event_paranoid=3(и на части хостов даже при 1) ядро отказывает в perf/PMU в Docker даже сCAP_PERFMON. После 1.8scripts/deploy.shи GitHub Actions при наличииdocker-compose.override.ymlпишут/etc/sysctl.d/99-birdlense-perf.confсо значением 0 иsysctl -p(ошибки игнорируются). INSTALL (EN/RU): при нехватке 0 — −1 вручную илиprivileged: trueв override. -
Метрики Intel GPU в Docker: при
intel_gpu_topс ошибкой PMUPermission deniedпредупреждение в лог не чаще раза в час (если после правок override ошибка останется). -
Логи процессора: «No detections after merge…» — не чаще раза в 120 с на уровне WARNING (между — DEBUG).
-
Логи FFmpeg при записи go2rtc: прогресс
frame=/ «Queue input is backward in time» / «Last message repeated» — DEBUG, итоговые строки — INFO. -
Файл-реплей UI: переключатель зацикливания — приоритет
desired.loopнадprocessor.loop, пауза ~4.5s без перезаписи из polling после клика, сброс при ошибкеloopMut. Upload 413: в Flask задан высокийMAX_CONTENT_LENGTH(переменнаяFLASK_MAX_CONTENT_LENGTHв байтах); в UI отдельный текст, если 413 похож на ответ прокси (не JSON хаба). Документация INSTALL/CONFIGURATION: nginxclient_max_body_sizeдля/api/. Встроенный nginx образа Hub: вdocker-nginx-main.confзаданclient_max_body_size 64g; дляlocation /api— длинныеproxy_*_timeoutиproxy_request_buffering off, чтобы прокси в контейнере не отсекал большие тела запросов. -
CI processor tests:
test_two_stage_strategy_integrationбольше не требует jay/bird в top-1 на1.jpg— реальные веса дают другие виды (напр. GYRFALCON в Docker); проверяется конвейер binary + species head и валидныеclass_name. -
Docker / fusion export: контекст сборки
birdlense— корень репозитория (docker-compose:context: ..,dockerfile: app/Dockerfile); в образ копируетсяscripts/export_fusion_training_data.py,repo_root()и E2E/тесты без монтирования..:/workspaceне ломаются. -
Тесты без пропусков:
test_settings_with_mcp_tokenзадаёт временныйmcp.token;test_regional_scope_true_for_birdnet_detectionсоздаёт и удаляет вид в БД;test_detection_strategyне подменяетultralytics, если пакет установлен (интеграции YOLO в Docker); Playwright smoke — пустой Overview безtest.skip. -
CI / Settings UI: ключ
general.session_idle_minutesизdefault_config— поле в Settings → Security (EN/RU), типsession_idle_minutes, при двух уровнях доступа PATCH для помощника снимает это поле (CONTRIBUTOR_ADMIN_ONLY_PATCH_PATHS). Ruff format дляapp/processor/src/interfaces.py. -
Docker / nginx (non-root): каталог
/var/log/nginxв образе принадлежитbirdlense;error_log/access_logуказывают туда же — без alert «could not open … /var/log/nginx/error.log» при старте. Кэшиapp/.ruff_cacheиapp/.pytest_cacheв.gitignore. См. TROUBLESHOOTING / RU.
-
Processor (#295):
DetectionStrategyProtocolвapp/processor/src/interfaces.py;FrameProcessorаннотирован протоколом; тестtest_detection_strategy_protocol.py. Док: ARCHITECTURE / RU § Maintainability baseline; REPOSITORY_LAYOUT / RU — составapp/processor/. -
#279: опциональный строгий режим UI API — при production и
BIRDLENSE_STRICT_API_AUTH=1запросы к/api/ui/*требуют сессию (послеverify-password),BIRDLENSE_UI_API_KEY(X-Birdlense-Api-Keyили Bearer) или MCP Bearer; исключения:health,requires-password,check-access,verify-password,vapid-public,logout, preflight OPTIONS. Docker Compose иscripts/deploy.shпробрасывают/сливаютBIRDLENSE_STRICT_API_AUTHиBIRDLENSE_UI_API_KEY; CI — отдельный шагtest_strict_ui_api_auth.py. См. SECURITY / ACCESS_CONTROL / CONFIGURATION / SECRETS_ROTATION / INSTALL (EN/RU),app/.env.example,scripts/deploy.local.sh.example. -
Web (#292): CORS и SQLite PRAGMA —
app/web/flask_extensions.py; старт схемы, seed, species registry, legacy cleanup и фоновый metadata repair/enrich —app/web/app_startup.py;app.pyостаётся тонкой фабрикой. Док: REPOSITORY_LAYOUT / RU, ARCHITECTURE / RU. -
#283: локальные CORS origins (Vite,
birdlense.local, порт хаба) заданы вconfig.Configи переменной окруженияCORS_LOCAL_DEV_ORIGINS(пустая строка — не добавлять встроенный набор);app/web/app.pyтолько собирает итоговый список вместе сCORS_DEFAULT_ORIGINS/CORS_ORIGINS. -
Весы / ESPHome MQTT (#228 комментарий, #232 закрыт): префикс
integrations.scales.mqtt_topic_prefix(birdlense/scale→ топикиweight,bird_present,command); процессор мержитbird_presentвfeeder_scale_state.json;POST /api/ui/feed/scale-tareпубликуетmqtt_tare_payload(по умолчаниюTARE); карточка кормушки — строка присутствия и кнопка тары (админ). Ключиmqtt_command_topic/mqtt_tare_payloadв YAML. Документация: CONFIGURATION (EN/RU). -
Processor (tech debt #225 / #238): цикл motion → запись и финализация вынесены в
MotionRecordingSession(app/processor/src/recording_session.py);main.pyоставляет сбор зависимостей и вызов сессии. -
Web (миграции схемы, #225): вместо try/except
ALTER TABLEна старте — Flask-Migrate / Alembic (app/web/migrations/, ревизия001_schema_patches, идемпотентные колонки); послеdb.create_all()вызываетсяupgrade(); зависимостьFlask-Migrateвweb/requirements.txt.
-
CodeQL (Python): в
.github/codeql/codeql-config-python.ymlдобавленыquery-filters— отключеныpy/reflective-xss(ответы JSON черезjsonify),py/stack-trace-exposure(краткие ошибки клиенту) иpy/path-injection(ложное срабатывание наdata_pathsпри реальномrealpath/commonpath;recording_layout_pathsуже вpaths-ignore). -
openapi-contract: Radon — закрепить
radon==6.0.1(на PyPI нет 6.0.5; шаг «cyclomatic complexity» падал наpip install). -
#286: job
ui-build— послеnpm ciвыполняетсяnpm run lint, затем build; ESLint: плагинreact-hooksс правиламиrules-of-hooksиexhaustive-deps(без полногоrecommendedv7 с React Compiler rules). -
#284:
.github/workflows/npm-audit-scheduled.yml— еженедельно +workflow_dispatch:npm audit --omit=dev --audit-level=moderateвapp/ui; политика в комментариях workflow. Док: TESTING / RU.
-
Processor / Telegram: в CONFIGURATION / RU описан ключ
processor.min_confidence_to_notify(отдельный порог для фото в Telegram); в TROUBLESHOOTING / RU — почему после правокprocessor.*/detection.*нужен перезапуск processor. -
#234: гайд HEIMDALL / RU — шаблон URL для плиток linuxserver/Heimdall v2 (ручное добавление; без импорта в UI); опциональный HTML закладок для браузера в docs/examples/heimdall/; ссылки из CONFIGURATION / RU, навигация MkDocs.
-
#287: аудит завершён — в
create_app/рантайме web нетALTER TABLE; DDL только в Alembic; зафиксировано в ARCHITECTURE / RU (политика DDL + PRAGMA). -
Синхронизация с кодом и CI: обновлены TESTING.md / TESTING.ru.md (полный перечень job workflow CI), ARCHITECTURE / RU (Alembic/Flask-Migrate), REPOSITORY_LAYOUT / RU (
create_app, migrations, services), ROADMAP / RU (версии React/Vite изpackage.json, строка про схему БД, волна maintainability #292–#297 + security #277–#287), README / RU, Documentation / RU (чеклист ревью), VERSIONING / RU, корневые CONTRIBUTING / RU. Ссылки на корневойCHANGELOGи.github/workflows/ci-pr.ymlведут на GitHub, чтобыmkdocs build --strictне ругался на пути внеdocs/. -
Roadmap / техдолг: #201 отмечен закрытым, активный processor backlog — #238; обновлены ROADMAP.md, ROADMAP.ru.md, пример
github-issue-link-subissues.sh. Эпик #220 в заголовке ссылается на processor #238. -
Техдолг — переоценка плана: тело #220 переписано (статусы #221–#224/#198/#201, таблица «что сделано / что осталось»); #225 и #238 синхронизированы с кодом (
build_detection_stack,is_mqtt_live/is_mqtt_ok_for_heartbeat).
- Processor / eBird (#238): вынесен общий модуль
app/ebird_region_core.py(регион, HTTP top-N, кэш, маппинг имён черезapp_config). Процессорebird_regional_confidenceбольше не импортируетservices.*;ebird_region_serviceиebird_util.REGION_NAME_TO_CODEиспользуют core. Docker:COPY ebird_region_core.py.
-
Ручная коррекция вида (UI): по умолчанию
PATCH /api/ui/detections/:idбольше не используетlegacy_fanout(обновление всех строк того же вида на ролике + синхронный FFmpeg для датасет-кропов на каждой строке), из‑за чего запрос мог занимать минуты и «вешать» вкладку. Теперь по умолчаниюsingle_track(как сценарий Unknowns / одна строка); страница видео явно передаётapply_scope: legacy_fanout. При большом числе затронутых строк перенос/извлечение кропов датасета уходит в фоновый поток послеcommit. -
Processor / MQTT (#238): при обрыве брокера исходящая очередь не сбрасывается;
publish_detectionставит сообщения в очередь и при кратковременном offline (если брокер настроен); слив только при живом сокете.stop()по-прежнему очищает очередь. -
Деплой: rsync больше не синхронизирует корневой каталог
datasets/(локальные данные для обучения), чтобы не заливать гигабайты на VPS. -
Code review (PR #235): пустой дефолт
homeassistant.urlвdefault_config.yaml— снова работает fallback наweather.ha_urlпри апгрейде; безопасныйintдляhistory_max_linesв процессоре; журнал весов обрезается по числу строк, а не только после 512 KiB; миграцияscales_weight_delta_kg— игнор только дубликата колонки, остальные ошибки логируются и пробрасываются; OpenAPISettings— блокhomeassistant; валидация min в UI для порога/дебаунса триггера по весам; уточнены CONFIGURATION и RU-локали.
- Timeline / карточка визита: в ответе
/api/ui/timelineи в UI (VisitCard) полеscales— оценка дельты весов с «основного» ролика визита (как на странице видео). #228 закрыт.
- Деплой:
scripts/deploy.sh— rsync исключаетapp/data/целиком иapp/.env, как в.github/workflows/deploy.yml; локальные записи/БД/images на VPS не затираются приmake deploy. - Processor (tech debt #225, шаг 1): из
main.pyвынесеныprocessor_support(логирование, heartbeat, restart flag, пути записи) иnotify_preview_encode(превью для уведомлений). - Processor (tech debt #224): исходящие MQTT-публикации из потока записи идут в очередь и отправляются только из потока сетевого цикла (
Client.publish— single writer); циклloop_foreverзаменён наloop+ слив очереди.frame_processor: при слабом свете троттлинг безsleep(1)на критическом пути записи (#224). - Настройки → General: подсказка
heimdall_url— явно указано, что Heimdall не импортирует сущности BirdLense; URL только для проверки доступности с Hub; плитка на хаб и/metrics— вручную. - Трекинг: #167 закрыт (основной объём весов); #228 (дельта на карточке визита) закрыт после реализации в timeline/UI; ROADMAP обновлён.
- Настройки весов (UI): при источнике Home Assistant — информационный блок, почему нет опций дельты/триггера (процессор только MQTT); CONFIGURATION — уточнён разрыв
mqttvshomeassistant. - Home Assistant: URL и Long-Lived Token вынесены в отдельную секцию
homeassistant.*и блок настроек «Home Assistant» (общие для погоды, весов сsource: homeassistantи др.); в «Погода» при источнике HA остаётся толькоweather.ha_entity_id. Устаревшиеweather.ha_url/weather.ha_tokenпо-прежнему читаются как fallback и помечаются в аудите конфига; те же ключи игнорируются в списке «unknown» аудита. EnvHA_URL/HA_TOKENпо-прежнему перекрывают YAML. - Scales: убран ключ и переключатель
integrations.scales.estimate_require_video_detection— дельта веса за клип по умолчанию и всегда не пишется для роликов только с BirdNET (audio); звук остаётся для вида, не для привязки к весам. Docker: лимиты контейнера хаба 4 CPU / 4G, Redis 256M maxmemory, Gunicorn 16 потоков по умолчанию; кэш API по-прежнемуperformance.cache_redis_enabled: true+REDIS_URLв compose. - Web (PR #227 follow-up): кэш
filter_feeder_species— сигнатура каталога Species учитывает суммуlength(name)(переименования без смены id/parent);bust_feeder_species_filter_cacheпосле seed / backfill (не dry-run) / materialize-allowlist species-registry;app/pyproject.toml— interrogate с порогом 80% (исключёнtests, игнор вложенных функций,__init__, magic и_semiprivate);make docs-checkзапускаетinterrogateизweb/без принудительного успеха. - Processor (tech debt #223): единая сборка пайплайна детекции —
detection_stack.build_detection_stack(resolve_single_stage_model_path, стратегия two/single stage,FrameProcessor,DecisionMaker, eBird overrides);main.pyиtrack_regenerator.build_detection_pipelineиспользуют её вместо дублирования (#223). - Web (tech debt #223): маршруты метрик/visitors/history — в
ui_system_metrics_routes; species-registry — вui_system_species_registry_routes; изui_system_routesубраны дубликаты эндпоинтов (одна регистрация на Flask) (#223). - Web (tech debt #198 закрыт): публичные
/api/ui/*вынесены из монолита в доменные модулиui_*_routes;ui_routes.py— толькоregister_routesи реэкспорт хелперов таймлайна (build_merged_timeline_items,parse_timeline_iso). См. ARCHITECTURE (#198). - Follow-up (PR #227 review):
data_paths— единый_resolved_path_under_data_dir, безопасныйfull_path_for_video(только подDATA_DIR);timeline_payloads— сравнение окон визитов в aware UTC;visitors/track— лимит POST по IP, сброс только префиксаsystem_visitors:, retry приIntegrityErrorна уникальном(browser_hash, seen_day); seed/backfill species-registry — инвалидация кэшей;observer_time— даты солнца из astral, вечер до конца суток;detection_stack— предупреждение при fallbackyolov8n.pt;species_metadata— отсутствиеhierarchy_names.txt,build_hierarchy_treeчерез_load_hierarchy_parent_map. - Web / SQLAlchemy 2.x:
ActivityLogиVideoзагружаются черезdb.session.get(...)вместо устаревшего.query.get()(processor_routesactivity log,gallery_upload_service). Processor: docstring уDecisionMaker.decide_stop_recording, комментарий к ключу(key, -1)вspecies_normalizer(#221). - Processor (tech debt #222):
ebird_regional_confidenceбольше не правитsys.path— импортservices.ebird_region_serviceпри нормальномPYTHONPATH(/app:/app/webв Docker). MQTT: разведеныis_mqtt_live()(сокет к брокеру) иis_mqtt_ok_for_heartbeat()(с запасом после обрыва); heartbeat UI — второй, выбор Frigate primary и motion — первый (#222). - Web (tech debt #222): лимит попыток verify-password,
Retry-Afterиclient_ip_for_rate_limitперенесены изutil.pyвauth.py; вutilоставлен re-export для обратной совместимости (#222). - Web (tech debt #222): Wikipedia / iNaturalist, allowlist хостов для прокси, seed-иерархия и канонический маппинг видов,
update_species_info_from_wiki,filter_feeder_speciesвынесены вspecies_metadata.py;util.pyреэкспортирует прежние имена (#222). - Web (tech debt #222):
get_primary_video_for_visit*,format_visit_for_timeline,format_unlinked_video_for_timelineвынесены вtimeline_payloads.py;utilреэкспортирует их для существующих импортов (#222). - Tech debt #222 закрыт: разгрузка
util.pyдоведена до конца — фасадutil+species_metadata,timeline_payloads,data_paths,observer_time,time_util,metrics_auth,species_constants,compat_reexports; обратная совместимость через реэкспорты. Прогон:make test,make test-web; деплой на площадку —make deploy. - Web (tech debt #222):
compat_reexports.py— реэкспорт auth / notifications / weather_service;utilподтягивает их черезimport *(#222). - Web (tech debt #222):
species_constants.py—GENERIC_BIRD_SPECIES; потребители импортируют напрямую,utilреэкспортирует (#222). - Web (tech debt #222):
time_util.py—ensure_utc,parse_utc_timestamp;metrics_auth.py—metrics_bearer_denied;utilреэкспортирует (#222). - Web (tech debt #222): каталог данных и безопасные пути к файлам — в
data_paths.py(_data_dir,read_safe_image_bytes,recordings_dir,full_path_for_video, …); часовой пояс наблюдателя и солнечные интервалы — вobserver_time.py;utilреэкспортирует прежние имена (#222). - Follow-up (PR #226 review): очистка устаревших IP в счётчике verify-password; разбор
Authorizationдля метрик с регистронезависимымBearer; Frigate остаётся primary motion при старте даже если MQTT ещё не live; MQTT-only детекции вspecies_normalizerне затирают друг друга приone_per_species; OpenAPI —400для/system/activity, путь/system/logs; UI Overview без небезопасного cast погоды; правки доков scales/DATA_DIR; устойчивостьgithub-issue-link-subissues.shк 404 отgh api.
- Деплой:
scripts/deploy.local.sh.exampleи DEPLOY_SERVER описывают два равноправных режима — LAN (на площадке:192.168.1.11:22, UI:8085) и удалённый (VPS203.0.113.10:2222как пример TEST-NET-3, UIhttps://hub.example.com/или IP); вdeploy.local.shдержать активным один блок и переключать при смене места работы. - Tech debt: эпик #220; sub-issues #198 (закрыт — модульные
ui_*_routes), #201 (закрыт — PR #237), #238 (processor фаза 2:MotionRecordingSessionсделано), #221–#225 (#225 в хабе: Alembic001+ сессия записи сделано);scripts/github-issue-link-subissues.sh. ROADMAP.ru.md — волна D. - Scales / roadmap: #167 и #228 закрыты. CONFIGURATION —
integrations.scales.*(MQTT / Home Assistant).
-
UI (Overview): карточка погоды больше не пропадает из сетки: пока
/api/ui/weatherгрузится, показывается скелетон; сбой погоды не блокирует весь обзор — только блок погоды с кнопкой «Повторить». -
CI: синхронизация
app/ui/src/generated/openapi-types.tsсopenapi.yaml(шагcodegen:openapi+git diffв workflow). -
CI:
ruff formatдляweb/services/readiness_service.py,web/tests/test_system_stabilization.py. -
npm (Dependabot GHSA-r4q5-vmmm-2653): обновлён follow-redirects (транзитивно от axios) —
npm auditбез находок. -
E2E smoke (CI docker-tests): сценарий
/unknowns— ожидание финального URL/timelineбезreview=1для гостя (как в UI послеNavigate+ сброса review).
- Visitors track:
test_security_hardening.py— 429 при превышении лимита POST/api/ui/system/visitors/trackпо IP (PR #227). - Telegram proxy:
test_telegram_proxy.pyимпортируетutilкак топ-уровневый модуль (import util), в духеconftestи остальных web-тестов — избегает двойной загрузкиweb.utilvsutilи цикла сtimeline_payloads(#222). - Xeno-canto:
web/tests/test_xeno_canto_service.py— парсинг и ошибки сети через мокrequests.get;GET /species/.../xeno-cantoвtest_apiбез реального HTTP. Шаг в CIopenapi-contract(#202). - Birdfood / Web Push:
web/tests/test_settings_mutations_smoke.py— 403 при закрытых настройках, POST+PATCH кормушек, дубликат имени, успешныйpush/subscribeпри включённых уведомлениях. CIopenapi-contract(#202). - Тот же файл: стрим видео при
require_auth_for_video_stream— гость 403, contributor 200; успешныйPATCH /api/ui/settingsс ролью admin (#202). - Processor / system:
test_processor_videos_smoke.py— секрет, пустой species, порог confidence, успешный ingest, невалидные даты;test_system_routes_smoke.py— activity, metrics/history, logs (403/200). CIopenapi-contract(#202). - OpenAPI / CI:
openapi.yaml— ответ/overview(hourlyTemperature,lastDetection,observer_timezone,stats.detectionByProvider), схемаVideoNeighborsи query-параметры как в API; контракт-тестGET /videos/{id}/neighbors. В jobopenapi-contract— ruff только дляweb/tests/; мелкие правки импортов под ruff (#202).
- Metrics endpoints (optional auth): если задан
BIRDLENSE_METRICS_TOKEN,GET /metrics,GET /api/metricsиGET /api/metrics/summaryтребуютAuthorization: Bearer <тот же токен>(hmac.compare_digest); без переменной поведение как раньше (удобно для scrape в LAN). См. CONFIGURATION → Prometheus. - Code scanning (path injection): чтение и удаление превью для Telegram —
read_safe_image_bytes/remove_safe_image_fileвutil.py:realpath+commonpath+startswith(DATA_DIR + sep), затемopen/os.remove; логика вынесена изnotifications.py. Удалён_safe_image_path_or_none. Дляpy/path-injectionна sink-строках —# lgtm[py/path-injection](путь уже ограничен каталогом данных); иначе анализатор не снимает taint сrealpath(path)доopen/remove.
0.3.4 - 2026-04-09
Патч CI/доков и синхронизация версии перед слиянием ветки настроек/UI.
- Документация (MkDocs
--strict): в CONFIGURATION (EN/RU) ссылки на стартовые профилиapp/configs/*.yamlведут на GitHub (blob/main/...), чтобы сборка сайта доков не падала на «файл не найден» относительно дереваdocs/. - Processor / тесты: более устойчивые сценарии MQTT (пустой
motion.frigate_label_filter,topic_matches_subкак в paho) и таймингpost_recordв CI.
- Версия проекта 0.3.4 (
VERSION, OpenAPI, MkDocssite_version, UIpackage.json).
0.3.2 - 2026-04-03
Патч безопасности и документации после v0.3.1: CodeQL, прокси изображений, доработки по итогам ревью PR, синхронизация версий.
- CodeQL-driven hardening (Python): species image proxy (
GET /api/ui/species-image) follows redirects manually with an allowlisted host check on every hop; each request uses a URL rebuilt from parsed host/port/path (no userinfo). Client-facing proxy errors are generic; details only in server logs. Telegram/notification image paths use_safe_image_path_or_nonethat returns only a resolved path underDATA_DIR. Go2RTC: connect log omits URL-derived fields (credentials never hit log lines). eBird region comparison cache key uses SHA-256 (truncated) instead of MD5. Species catalog allowlist parsing avoids a polynomial-ReDoS-prone regex. - Follow-up (security review on PR #218): iNaturalist open-data allowlist for the species image proxy is hostname-only (
_host_is_inaturalist_open_data_asset) — no substring match on the full URL (closes query-string SSRF bypass).urlparse/hostname/portwrapped where needed to avoid 500 on malformed URLs._is_safe_image_path/_safe_image_path_or_noneuseos.path.commonpathagainstDATA_DIRto blockdata_evil-style prefix tricks. Regression tests added. - UI (
app/ui): refreshedpackage-lock.jsonandoverridesso lodash resolves to ≥4.18.0 (addresses GHSA-r5fr-rjxr-66jc, GHSA-f23m-r3pf-42rh); serialize-javascript pinned via override to ≥7.0.5.npm auditclean. Pythonrequests/ Flask-Cors were already at patched versions inapp/webandapp/processorrequirements.
- Docs / repo hygiene: added REPOSITORY_LAYOUT (EN/RU) for onboarding; moved publication drafts to
docs/article/; refreshed docs index version line and roadmap stack (Ultralytics pip vs Docker base). Root.gitignorenow ignores/.pytest_cache/. - Docs refactor: MkDocs
navaligned with SITE_MAP —DEPLOY_SERVER,VERIFICATION, pre-implementation checklist,UX_TOOLTIPS, Russian A11Y / REPOSITORY_LAYOUT;INSTALLcross-links the deploy checklist; API version line tracks rootVERSION; ROADMAP changelog links use project/changelog;article/**andCONSILIUM_AUDIT.ru.mdexcluded from the static site build; ROADMAP anchor IDs fixed for strict builds. - Contributor docs: removed
AGENTS.md; maintainer workflow lives in CONTRIBUTING / RU. GOVERNANCE / RU, MCP_SETUP, OpenAPI description, PR template, CodeQL/local dev guides, and related copy updated for a standard open-source tone (human reviewers, VS Code). - Docs: MCP again documented explicitly as Model Context Protocol for authorized automation and integrations (README, OpenAPI narrative, FEATURES, GLOSSARY, MCP_SETUP EN/RU).
0.3.1 - 2026-04-04
Патч после v0.3.0: обновления зависимостей и согласованность Docker/CI. Merge: #213; gunicorn: #208.
- Processor:
ultralytics==8.4.33вapp/processor/requirements.txt(обновление пакета черезpipв образе). - Web:
gunicorn23.x → 25.3 вapp/web/requirements.txt. - UI (dev):
eslint-plugin-react-hooks^7.0.1 (app/ui/package.json/ lockfile).
- Docker / CI: базовый образ остаётся
FROM ultralytics/ultralytics:8.4.21— при8.4.33в базе ломалась сборка динамического модуля ngx_brotli под nginx из образа (cc … -Werror). Версия Ultralytics для рантайма процессора задаётся pip-слоем.
0.3.0 - 2026-04-03
Накопительный релиз после v0.2.10: обзор и таймлайн, границы Library/System, ужесточение API и CI. Merge: #211.
- Overview / Timeline / визиты: счётчики «всего визитов», графики топ-видов и «последний час» считают число визитов (строки
SpeciesVisit), а не суммуmax_simultaneousи не число сегментовVideoSpecies. Блок «По источникам» — сколько визитов содержат хотя бы один сегмент провайдера (с подсказкой, что сумма может превышать общее число визитов при слиянии источников).GET /api/ui/timelineи экспорт: дедупликация визитов послеJOIN(один визит с несколькими роликами больше не дублируется в списке и статистике). PDF-отчёт иget_monthly_report_dataвыровнены с той же семантикой. - Overview UI: карточка «Топ видов» — легенда под диаграммой (как «Суточный паттерн»), без обрезки из‑за
height: 100%/ overflow; масштаб как у суточного паттерна (hideLegend, размер 450). - Таймлайн «Записи»:
GET /api/ui/timeline(и экспорт) дополняется роликами за выбранный интервал, которые ни к одному визиту не привязаны — они отображаются отдельными карточками с пометкой «Запись без визита» (timeline_kind: unlinked_video, отрицательныйidв JSON). Листание prev/next на странице видео снова по всем роликам за локальный день (как в архиве), без режимаvisit_day. - Cleanup / legacy removal: removed dead Library/System UI leftovers (
RecordingsAndDataset,SystemActivity, dormant BirdDirectory page/help/i18n), so legacy dangerous controls can no longer reappear through accidental imports. - Backend surface hardening:
/api/ui/status/debugnow requires authenticated admin settings access; legacy sync species-registry maintenance routes were removed in favor of the active asyncstart/statusflow. - Docs / operator parity: TESTING, CONFIGURATION, and ARCHITECTURE docs now match the live routes and current species/catalog UI model.
- CI: аудит карточек каталога (
audit_species_cards.py) — опции--ignore-direct-image-429,--ignore-empty-description,--ignore-empty-image-urlи меньше воркеров в PR: не фейлить на 429 Wikimedia и на незаполненных карточках минимальной БД CI. settings-ui-coverage: сканирование всех*.tsxвSettings/(поля Go2RTC в секциях), allowlist для новых ключейprocessor.track_regen_precise_*иspecies.tuning_target_species_ids.POST /api/ui/system/db/restore: при отсутствии файла в multipart сначала ответ 400 (раньше при отсутствии live SQLite на диске мог вернуться 404 до проверки загрузки).- Stabilization / safety:
POST /api/ui/system/realign-visit-timesnow exists with honest preview/apply flow;clean-orphaned-visitspreview no longer mutates the DB; production no longer treats empty passwords as an implicit admin unlock for system/settings flows. - Library / System boundary: Library now shows a real recordings-on-disk calendar instead of processor heartbeat and points operators to System for maintenance; heartbeat activity moved to System.
- Overview / cross-day visits: Overview now counts visits that overlap the selected day and buckets cross-midnight visits into the selected day instead of the previous day’s hour.
- Species merge integrity: merging species rows now preserves missing target metadata (description, image, metadata source) instead of silently dropping it.
Накопительный релиз после v0.2.9: каталог/реестр, производительность, Telegram/MTProto, CI/E2E, перегенерация треков. Merge: #196.
- Перегенерация треков: частичная замена по выбранным видам (
species_ids); сопоставление детекций с каталогом по таксону и имени;GET /api/ui/species/track-regen-options— виды с треками на видео (VideoSpecies); при фильтре по виду период запроса — весь охват библиотеки из storage stats; ручные правки — сопоставление вида по таксону, не только построчное равенство имён; лог при пустой очереди сspecies_ids.
- CONFIGURATION / Telegram: раздел «если my.telegram.org выдаёт ERROR» — обход через SOCKS/HTTP или без прокси без api_id; уточнены ключи
telegram_proxy_typeи MTProto. - CONFIGURATION / Telegram: добавлены простые команды для авто-ротации прокси на сервере:
make proxy-rotation-install,make proxy-rotation-status,make proxy-rotation-remove. - INSTALL / docs index: добавлен короткий путь «one-command setup» для Telegram proxy autorotate в
INSTALL(.ru).mdиdocs/README(.ru).md(установка, статус, отключение, one-shot).
- Каталог видов / allowlist классификатора:
species.catalog_allowlist_file+species.catalog_strict_ingest— список классов из обучения (скриптscripts/datasets/dump_classifier_allowlist.py), строгий импорт вне списка → «Unknown».POST /api/ui/system/species-catalog/reconcile— слияние дубликатов по нормализованному имени, перенос подозрительных (блоклист) и строк вне allowlist на «Unknown». Блоклист также отсекает новый мусор на импорте. - Согласованность классификатора и датасета:
GET /api/ui/system/species-registry/classifier-dataset-alignment— классы изprocessor.models.classifier(как у процессора), каталогSpeciesи папкиdata/dataset/train|val; карточка System «Классификатор, каталог и датасет». Подсказка в отчёте data-quality. - Каталог видов / качество данных:
species_suspect_blocklist.txt— скрытие не-птиц и «вещей» в справочнике (GET /api/ui/species?exclude_suspects=1), карточка System «Качество каталога»,GET /api/ui/system/species-registry/data-quality(отчёт, дубликаты имён для merge). Календарь миграции исключает те же строки; кэшmigration_cal:v2. - Deploy / статика: rsync больше не исключает весь
app/data— на сервер попадаетapp/data/images(иконки корма и т.д.); записи и БД по-прежнему вapp/data/recordings,app/data/db. В образе —data/imagesв/_bundled_dataи копирование в/app/data/imagesпри старте контейнера (fallback). - Миграции / UI+API: фильтры «только с активностью» vs «весь каталог» (
catalog) и «все визиты» vs «только с видео-детекцией» (evidence). Связь с планом #125. - Детекция без дообучения:
detection.cross_source_confidence_bonus(по умолчанию 0.02) — одноразовый бонус к confidence при первом слиянии MQTT (Frigate/BirdNET) в существующую YOLO-детекцию. - System / observability: карточка «Наблюдаемость уведомлений» — счётчики
notify_preview_24hи подсказка по URL экспорта метрик Hub для Heimdall/Grafana;GET /api/ui/system/observability(с авторизацией настроек),GET /api/metrics/summary(JSON, тот же смысл, что и/metrics). - Docs / Heimdall: явно описано направление данных: метрики отдаёт Hub (
/metrics,/api/metrics/summary), в Heimdall добавляют ссылку на хаб; полеheimdall_url— только проверка доступности Heimdall с сервера Hub; проhttp://heimdall.localи резолв из Docker. - Gallery: нормализация JPEG (мин. размер, ограничение стороны) и fallback на полный кадр, если кроп по bbox не удался — ближе к надёжности Telegram-превью.
- Telegram / прокси: выбор типа — без прокси, SOCKS5 / HTTP (URL) или MTProto (сервер, порт, секрет hex как в приложении Telegram). MTProto-режим отправляет сообщения через Telethon (нативный MTProto); нужны api_id и api_hash с https://my.telegram.org или переменные
TELEGRAM_API_ID/TELEGRAM_API_HASHв окружении. Зависимость:telethon. Paid Media (Stars) в MTProto-режиме не поддерживается — отправляется обычное фото. - Ops / Telegram:
scripts/manage-telegram-proxy-rotation.shи make-таргеты для установки cron-авторотации (по умолчанию каждые 6 часов). Ротация запускаетscripts/refresh-telegram-proxy.shна самом сервере (BIRDLENSE_PROXY_LOCAL=1), выбирает лучший рабочий SOCKS5 и обновляетuser_config.yamlтолько при изменении. - Настройки: блок «Производительность / кэш API» — включение Redis и опциональный URL (
performance.*); секретный URL маскируется в API; в GET /settings добавлено read-only полеperformance.redis_url_effective_masked— фактический URL (в т.ч. изREDIS_URL), пароль замаскирован; в форме — placeholder и строка «Сейчас используется». - Весы у кормушки:
integrations.scales— источник MQTT (топик с числом/JSON, совместимо с ESPHome/HA) или сущность Home Assistant; отображение веса на главной в карточке кормушки; процессор пишетdata/feeder_scale_state.json. - Heimdall integration: новый ключ
general.heimdall_url(Settings → General) и серверный probe в разделе System (доступность, HTTP-статус, latency, title/version если доступны). - System UI / ревизия: новая карточка «Ревизия конфигурации» на странице System (
/api/ui/system/config-audit) — показывает deprecated/unknown keys, Telegram photo/proxy, gallery URL и статус Gray/Grey mapping.
-
Видео в UI: поток
/api/ui/videos/:id/streamпо умолчанию доступен гостям (как в ACCESS_CONTROL); опциональноgeneral.require_auth_for_video_stream: trueдля прежней блокировки. -
System / каталог: карточки качества каталога и согласования классификатора свёрнуты в аккордеон «Диагностика каталога»; смягчены подсказки в UI.
-
Старт Hub / containment: тяжёлые мутации БД на старте по умолчанию выключены —
BIRDLENSE_STARTUP_BACKFILL_SPECIES_TAXA,BIRDLENSE_STARTUP_CLEANUP_LEGACY_IMPORT,BIRDLENSE_STARTUP_REPAIR_SPECIES_METADATA; Telegram «App is UP!» —BIRDLENSE_NOTIFY_APP_STARTUP=0. См. CONFIGURATION. -
GET
/api/ui/species/:id/summary: только чтение (без Wikipedia/commit); в ответеmetadata_statusиmetadata_trust. -
Processor: single-stage COCO — только класс
bird; приboxes.id is Noneповторныйtrackна том же кадре; зависимостьlapдля ByteTrack; ESLint —ignoresдляdist/node_modules. -
CI (PR): после web-тестов — E2E smoke Playwright против локального
docker compose up. -
Деплой: при
BIRDLENSE_ENV=productionна удалённыйapp/.envидемпотентно дописываютсяTRUSTED_PROXY=1иBIRDLENSE_STARTUP_CLEANUP_LEGACY_IMPORT=1, если ключей ещё нет. -
Донаты: только иконка в шапке (рядом с языком и настройками); убраны из карточки «Корм» и из меню шестерёнки; URL по-прежнему в настройках (Общие → ссылка для поддержки).
-
Системная нормализация Gray/Grey: добавлены канонические пары в
detection.species_mappingиspecies_canonical_mapping.txt(Gray-headed Woodpecker/Great Gray Shrike→Grey-*), чтобы исключить рассинхрон имён между источниками. -
Telegram: подсказка про MTProto vs Bot API (HTTPS); прокси — SOCKS5h или HTTP(S).
-
Пороги детекции (дефолты в репо): снова нейтральные значения
min_track_duration4,min_confidence_binary0.22,min_confidence_to_process0.36,detection.min_confidence_to_store0.36 (без лишнего ужесточения). Продакшен-хаб настраиваетсяuser_config.yamlна сервере (не в git): там заданы рабочие пороги под площадку. -
Обзор: подсказки при наведении на все карточки ключевой статистики (раньше только «Время записи»).
-
Локализация / кормушка: «Реле кормушки» → «Кормушка» (раздел настроек про выдачу корма, весы и реле).
-
Каталог корма: позиция «Apple pieces» убрана из дефолтного списка; при старте старые строки с таким именем удаляются вместе со связями в
video_bird_food_association(общая категория Fruit остаётся).
- Gunicorn:
gthread+ 8 потоков (переменнаяGUNICORN_THREADS),--timeout 0— воркер не рвёт долгие стримы; параллельные запросы при одном процессе. - SQLite:
check_same_thread=False, таймаут подключения 30 с; при старте соединения — WAL,synchronous=NORMAL,cache_size~64 MiB,temp_store=MEMORY. - Nginx: gzip для JSON/JS/CSS/XML; upstream keepalive к Gunicorn (
proxy_http_version 1.1, пустойConnection); open_file_cache для статики. - Кэш ответов API (TTL):
/status5 с;/species45 с;/species/observed45 с;/bird_families300 с;/migration-calendar120 с;/timeline20 с;/unknowns12 с;/detection-frames45 с;/species/:id/summary30 с; Xeno-Canto 600 с. Сброс кэша:services/http_response_cache.bust_response_caches()— после PATCH настроек, правок детекций, merge видов, удаления видео и POST/api/processor/videos(новая запись). - Убран
app_config.reload()изGET /api/ui/feed/infoна каждый запрос. - React Query:
refetchOnWindowFocus: false,retry: 1,gcTime15 мин — меньше лишних запросов при переключении вкладок. - Страница видео / стриминг: GET
/api/ui/videos/:idбольше не включает покадровыеframes(часто мегабайты JSON) — оверлей треков подгружаетGET /api/ui/videos/:id/detection-framesпараллельно; плеер и метаданные появляются сразу после лёгкого ответа. Nginx: для/api/ui/videos/*/streamотключеныproxy_bufferingиproxy_request_buffering, увеличены таймауты чтения/отдачи — быстрее старт MP4 по HTTP Range. - Backend кэширование (#203):
services/cache.py— in-memory TTL или Redis приREDIS_URL./api/ui/overviewи region-comparison — как ранее; тяжёлые эндпоинты «Система» и хранилище — TTL-кэш с инвалидацией после purge/retention/scan/clean visits и merge видов. Redis по умолчанию в Docker: сервисredis(birdlense-redis) вdocker-compose.ymlиdocker-compose.pull.yml,REDIS_URL=redis://redis:6379/0,depends_on+ healthcheck. Nginx Brotli — динамический модульngx_brotliв образе. PostgreSQL:DATABASE_URL+ пул вconfig.py; пример только Postgres:app/docker-compose.stack.example.yml. Зависимости:redis,psycopg[binary]. - React Query staleTime:
staleTime=5 минна 4 редко-изменяемых запроса (bird-directory, species, observed) — меньше лишних refetch.
util.py→ 3 модуля:auth.py(аутентификация и rate-limit),notifications.py(Telegram + Web Push),weather_service.py(WeatherFetcher / HAWeatherFetcher / fetch_weather).util.pyсохраняет re-exports — все существующие импорты работают без изменений. Убраны ~591 строк дублирования.SettingsForm.tsx→ секции:sections/GeneralSection,VideoSection(позже удалён),ProcessorSection,NotificationsSection,EBirdSection,IntegrationsSection;shared/ServiceBlock,CamerasListField. Главный файл стал оркестратором (< 120 строк).- React Error Boundary:
components/ErrorBoundary.tsx+ оборачивает<Routes>вApp.tsx— несломанный рендер при runtime-ошибках в дочерних страницах.
- Telegram MTProto: корректный разбор
telegram_api_idи порта прокси из YAML/чисел (в т.ч.12345.0), чтобы после сохранения настроек не «терялся» api_id. - Telegram preview: нормализация фото перед отправкой (
Pillow+ fallback черезOpenCV) и upscaling очень маленьких кропов (минимум 64px), чтобы снизить ошибки Bot APIIMAGE_PROCESS_FAILED. - Telegram notifications UX: для детекций передаётся deep-link на конкретную запись (
/videos/{id}) вместо общегоlive; превью теперь имеет fallback-кроп из сохранённого видео поframes.bbox, еслиbest_frameотсутствует; кнопка в TG — более нейтральная (Open video/Open live). - Telegram notifications reliability: чтобы избежать «пустых» уведомлений, добавлен дополнительный fallback на полный кадр из видео, если нет
best_frameи нет валидногоbboxдля кропа. - Notifications observability: добавлены логи источника превью (
best_frame/bbox_crop/full_frame/none) и метрика Prometheusbirdlense_notify_preview_24h{source=...}по даннымactivity_logза 24 часа. - Статус MQTT в шапке: при работающем процессоре индикатор берёт
mqtt_connectedиз heartbeat (тот же клиент, что Frigate/BirdNET). Дополнительно: проверка из веб-процесса ждёт до ~2 с послеloop_start()и нормализуетmqtt.portв int — меньше ложных «ошибок» из-за гонки. - UI (страница видео): кнопки «предыдущая / следующая запись» не работали из‑за обращения к несуществующей переменной
listReturnState(ReferenceError в обработчике). Исправлено:useLocation(), сохранениеstate.fromпри переходе к соседним роликам (как с Timeline / Unknowns). Журнал проверок: VERIFICATION.ru.md / EN. - UI / доступ:
GET /api/ui/settings/check-accessвсегда отвечает 200 с{ unlocked: false }, если сессия не разблокирована (раньше 403 — шум в консоли браузера). Защищённые POST/PATCH по-прежнему возвращают 403 без сессии. - Processor: удалён legacy-compat флаг для старого single-stage COCO animal-only режима; runtime и конфигурация сведены к production-пайплайну
two_stage.
- UI: Migration — режим периода «по годам» или «по датам» (без одновременного показа четырёх полей). «Поддержать» в шапке на всех страницах (включая главную): сердце с анимацией пульса, то же в мобильном меню и в меню шестерёнки.
- UI: запрос
settings-check-accessв React Query —staleTime60 с, меньше лишних refetch при навигации. - CI / Deploy: workflow Deploy —
concurrency(один активный деплой наmain),timeout-minutes: 45,permissions: contents: read; шаг Verify падает сexit 1, если health недоступен (раньше только печатался FAIL). upload-artifact в CI и E2E → v6 (Node 24, без предупреждения о Node 20). INSTALL / RU: пояснение про Queued и fallbackmake deploy. Rsync в autodeploy — добавлен--exclude=app/.env. - Зависимости / безопасность:
app/ui—npm audit fix(транзитивные обновления, в т.ч. brace-expansion, picomatch, yaml, цепочка доserialize-javascript);requests[socks]==2.33.0вapp/web/requirements.txt(SOCKS-прокси для Telegram);requests2.33.0 вapp/processor/requirements.txt. scripts/setup-auto-deploy.sh — скачивание runner по последнему релизу с GitHub API,RUNNER_ALLOW_RUNASROOT=1под root,./config.shс--unattended --replace. - CI / Deploy: шаг Verify — порт из
BIRDLENSE_PORTвapp/.envна сервере (иначе 8085), пауза 10 с и до 36 попытокcurlс интервалом 5 с послеmake pull(старт контейнера и приложения). Smoke workflow — исправлен маппинг порта контейнера (8080, по умолчанию entrypoint). - Процесс / документация: закрыт открытый хвост issues (#114, #118, #125, #163–#167): ворота UX-контекста для
area:webв CONTRIBUTING.md / RU; E2E — итеративное расширение в TESTING.md / RU; идеи зафиксированы в ROADMAP.md / RU (новый issue при появлении объёма).
- Settings / UI: поля в веб-настройках для прокси и сети Telegram (
notifications.telegram_proxy_url, API base, таймауты, сжатие фото); post-roll и блок «несколько камер + BirdNET MQTT» (processor.*); зарезервированные весыintegrations.scales.*(топик сохраняется, обработка — позже, #167). Web: зависимостьrequests[socks]для SOCKS5h. - Processor (#157):
processor.post_record_seconds— post-roll: увеличивает паузу без детекций перед остановкой записи (сумма сmax_inactive_seconds). - Processor (#129): опционально
processor.birdnet_mqtt_auto_confidenceи параметры delta/floor — более низкий порог классификатора для видов из недавних сообщений BirdNET по MQTT (по умолчанию выкл.). - Processor (#153):
processor.multi_camera_groups+multi_camera_confidence_boost— при Frigate-событиях одного вида с двух камер из группы прибавка кconfidenceпосле merge. - Roadmap: пункт консилиума №17 — стратегия детекции (two_stage vs single_stage+COCO, пороги в
user_config, дообучение бинарника); блок в ROADMAP.ru.md / EN, связь с #163. Дополнено: чеклист «не забыть» перед/после консилиума; раздел «Завершение задач → тестирование оператором» (#completion-then-operator-testing). - E2E (#118):
app/e2e/tests/migration.spec.ts— фильтр года на Migration и сброс на «все годы»; TESTING.md / RU — отладка отдельного файла (playwright test/--debug).
Релиз доступности и регрессионных проверок. Merge: #187, закрыт #117.
- Accessibility (#117): skip link to
#main-content, shared:focus-visiblering in the MUI theme, migration tablecaptionand labeled filter region, status dots asrole="img"witharia-label, darker Live button for WCAG contrast; E2E axe scans inapp/e2e/tests/a11y.spec.ts(@axe-core/playwright); A11Y.md / RU. Follow-up:filledPrimaryChip color (#047857), infoAlertlink/button contrast, migration heatmap cells (border + light tint),AvatarimgProps.alt, defaultaria-labelonCircularProgress, overview species legend chips (data-testid+ keyboard) for stable E2E.
Накопительный релиз после v0.2.7: страница «Система» (метрики, история, посетители), донаты в UI, eBird/датасет/реестр видов и волна багфиксов. Merge: #185.
-
Документация: FEATURES / RU и API / RU — эндпоинты «Система»: live-метрики,
/system/metrics/history,/system/visitors. -
Система / UI: метрики хоста (
GET /api/ui/system/metrics) отделены от статистики посетителей (GET /api/ui/system/visitors?days=…); смена периода посетителей больше не перезапускает опрос CPU; на странице «Система» — накопительные графики за сессию просмотра (опрос 5 с); убраны карточки кодирования/MQTT; ссылка «Поддержать» в шапке и мобильном меню скрыта на главной (остаётся карточка «Корм» и пункт в меню шестерёнки). Prometheus/metricsне выполняет лишних запросов по посетителям. -
Система / история метрик: таблица
system_resource_sample, фоновый sampler (~30 с, хранение 72 ч, отключаетсяDISABLE_SYSTEM_METRICS_SAMPLER),GET /api/ui/system/metrics/history; графики на «Системе» — серия с сервера + «хвост» живого опроса, выбор окна 6/24/48 ч. Интервал и хранение:BIRDLENSE_SYSTEM_METRICS_INTERVAL_SEC,BIRDLENSE_SYSTEM_METRICS_RETENTION_HOURS; см. CONFIGURATION,app/.env.example. -
Доки деплоя / MCP: основная площадка в правилах и примерах — LAN 192.168.1.11:22, UI http://192.168.1.11:8085/, MCP
http://192.168.1.11:8085/mcp; публичный примерhub.example.com— вdeploy.local.sh.exampleи MCP_SETUP (без реальных прод-хостов в репозитории).
-
Региональный топ eBird: авто-пороги классификатора (#128): процессор подмешивает в эффективные
species_confidence_overridesвиды из топа региона (послеebird.species_mapping) с порогомmax(floor, min_confidence_to_process − delta); ручные строки важнее; ключиprocessor.ebird_regional_top_*;PYTHONPATHпроцессора включает/app/web; см. CONFIGURATION.md. -
eBird species mapping hints (#136):
GET /api/ui/settings/ebird-species-mapping-suggestionsи кнопка в настройках — подсказки строк дляebird.species_mappingпо региональному топу eBird vs каталог; общий кэш топа с фильтром «Региональные» вebird_region_service; см. CONFIGURATION.md. -
Bird Directory regional filter (#132): «Региональные» строятся по топу eBird для региона из настроек (как Migration) и по видам с детекциями BirdNET MQTT; в ответе
GET /api/ui/species—regional_scope; кэш списка eBird ~30 мин; дока в CONFIGURATION.md. -
Donation / support surfaces (#121): при заданном
general.donate_urlссылка «Support» / «Поддержать» в шапке (desktop), в мобильном меню и в меню шестерёнки; общий кэшfeed-infoс карточкой Food на Overview; i18n EN/RU/DE; CONFIGURATION / ACCESS_CONTROL. -
Bird food catalog (#134): расширен дефолтный список кормов (в т.ч. EU: fat balls, hemp seed, oats, mixes, rapeseed, apple);
seed_bird_food()идемпотентно добавляет только отсутствующие поname; дока в CONFIGURATION.md / RU; тестtest_bird_food_seed.py. -
Production secrets runbook (#119): SECRETS_ROTATION.md / RU — перечень env/YAML, порядок ротации, проверка, откат, шаблон экстренной заметки; ссылки из SECURITY.md, CONFIGURATION.md, MkDocs nav.
-
Release hygiene (#120):
scripts/check-docs-version.pyсверяет корневойVERSIONсmkdocs.yml,app/ui/package.jsonиapp/web/openapi.yaml; чеклист в VERSIONING.ru.md / EN; шаг в CIopenapi-contract. -
Species registry (backend): сервис нормализации видов, API под админ/систему, smoke
test_species_registry.pyи шаг CI вopenapi-contract; операторская дока в TESTING.ru.md. -
Dataset export (train-ready):
dataset_info.jsonv2 сmanifestиquality, опциональныйtestsplit в UI, querytest_ratio/strict_qualityнаGET /api/ui/dataset/export, smoketest_dataset_export_service.pyв CI; описание в DATASETS.ru.md. -
Документация: подготовительный чеклист перед реализацией #131 / #139 — PRE_IMPLEMENTATION_UNKNOWN_TIMELINE.ru.md / EN; ссылка из ROADMAP.
-
#54 (CI): контрактный смоук OpenAPI — новый тест
app/web/tests/test_openapi_contract.pyи jobopenapi-contractв.github/workflows/ci-pr.yml(гейт на PR/push вmain/dev). -
#55 (Migration): life list / «виды за год» покрывается самой таблицей миграции (фильтр по годам + строки и столбец Σ); отдельный дублирующий блок-чеклист на странице убран.
-
#81 (phase C): единый журнал ручных правок Unknowns/Video — backend activity
species_correction+ endpointGET /api/ui/corrections/recent+ блок последних правок на странице Unknowns.
- Волна A (bugs): #158 ретроэкспорт с периодом подхватывает сирот без
Video; retention каскадно удаляетVideoSpecies/SpeciesVisitкак при API удалении записи. #160 poll regenerate spectrograms/tracks с timeout 120s. #152 после удаления видео — возврат поstate.fromили на/library. - Dataset export: при
strict_quality=1и ready_for_train экспорт отменяется, если хотя бы один класс не прошёлmin_images_per_class(явный отказ вместо тихого пропуска); чекбокс в Library; см. DATASETS.ru.md. - CodeQL / code scanning: устранены открытые Python-алерты без «принятия риска» —
urlparseдля источников метаданных, линейный разбор скобок вместо ReDoS-регекса,_safe_image_path_or_noneдля Telegram crop,mkstempв спектрограмме, редактирование URL в логах go2RTC; тестыtest_util_metadata.py; см. CODEQL.ru.md. - Migration UI: убран дублирующий блок «чеклист за год» над таблицей — те же виды и суммы уже есть в таблице миграции.
- #56 (CORS config): demo-host удалён из hardcoded CORS defaults; теперь базовые non-localhost origins задаются через
CORS_DEFAULT_ORIGINS(и runtimeCORS_ORIGINS), что безопаснее для self-hosting.
- Отчётность: без отдельных страниц
PROJECT_REPORTING*— правила в docs/contributor/roadmap.md / RU и CONTRIBUTING / RU; вести Issues и доску, не дублировать политикой вdocs/. - Доки окружения: примеры UI https://hub.example.com/, SSH
203.0.113.10:2222(документационные значения) — DEPLOY_SERVER / RU, MCP_SETUP / RU, примерscripts/deploy.local.sh.example. - #85 (video neighbors):
GET /api/ui/videos/:id/neighborsтеперь поддерживает локальный день (day_scope=local,tz_offset_minutes) и опциональный переход на соседние сутки (cross_day); UI страницы видео использует локальный режим по умолчанию. - #50 (processor MQTT resilience): MQTT-клиент процессора использует встроенный reconnect/backoff paho (
reconnect_min_delay/reconnect_max_delay), а в конфиг/доки добавлены параметры и пояснение про пропуски live-событий при обрывах. - Settings UI (MQTT): в форму добавлены
publish_topic,reconnect_min_delay,reconnect_max_delayдля полной настройки MQTT без ручного редактирования YAML. - CI/процесс:
settings-ui-coverageрасширен метаданными зрелости для non-UI ключей (ops-only,advanced,backend-managed,planned-ui) сreasonиnext_step; это даёт прозрачный план эволюции настроек, а не только pass/fail. - #51 (операторский UX): в System добавлены безопасные
SQLite backup/restore(скачивание бэкапа и восстановление из файла с авто-pre_restoreкопией), плюс документация в INSTALL/TROUBLESHOOTING. - #52 (UI i18n): добавлена пилотная третья локаль
de(German) вreact-i18next, улучшен выбор стартового языка (saved/browser/fallback), переключатель языка теперь полностью через i18n-ключи. - #107 (Overview stats): карточка «Средняя длительность» / Mean recording duration считает среднюю длительность одной записи (
Video), а не среднюю длительность визита (SpeciesVisit), чтобы метрика соответствовала названию.
- Project hygiene: скрипт
scripts/github-project-sync.shдля автосинхронизации доски (Status/Поток по состоянию issue, auto-assignee для open задач без исполнителя, отчёт по open задачам без checklist-подзадач). - #53 (CI): workflow
.github/workflows/docker-image-smoke.yml— ежедневный smoke-тест опубликованногоghcr.io/<owner>/birdlense-hub:latest(pull/run + проверка/api/ui/health). - #48: скрипт
scripts/datasets/export_birdlense_to_yolo.py— экспорт локальных кропов BirdLense (app/data/dataset/train) в YOLO classification layouttrain/valс детерминированным split иdataset_info.json. - #47 (maintainer hygiene): скрипт
scripts/security/scan_git_history_secrets.shдля прохода по полной git-истории через Gitleaks (Docker) + документированный процесс в SECURITY / RU.
0.2.6 - 2026-03-23
Накопительный релиз после v0.2.5: CI CodeQL, навигация по видео #82, деплой/Web Push, сопутствующие доки и инфраструктура репозитория.
- Деплой: rsync исключает
.tools/(локальный CodeQL изscripts/codeql-local.sh) — не заливать гигабайты на сервер. - Деплой (
scripts/deploy.sh): rsync исключает.venv-docs-tmp,.venv-docs,site/,app/.venv— не заливать локальные venv на сервер. - Web Push: при битых p256dh/auth или пустых ключах подписка удаляется из БД (раньше — предупреждение в лог на каждую отправку); pytest
web/tests/test_web_push_service.py. - Gallery: приём ответа приёмника 201 и 204 (раньше только 200); при отсутствии подходящих детекций — INFO в лог с причинами фильтра.
- Страница вида
/species/:id: валидация id; при 404 — понятное сообщение и ссылка в каталог; пустые weather / некорректная длина hourlyActivity не ломают графики (MUI Charts). API summary: обновление из Wikipedia обёрнуто в try/except, чтобы сеть/БД не отдавали «мёртвую» страницу. - Unknowns ↔ видео: после смены вида или merge на странице видео список «Неизвестные» больше не «залипает» на старых данных (инвалидация
['unknowns']вDetectedSpecies; раньше кэш жил до 5 минут). - Удаление видео: сначала коммит в БД, затем удаление папки записи на диске — при ошибке транзакции файлы не удаляются; после удаления — сброс кэша
video/video-neighbors/videosи инвалидация соседей по дню. - CI: сайт документации — без workflow на
release(деплой только сmain), чтобы не было failed deployment в списке при теге.
- CONTRIBUTING.md — полный цикл работы для мейнтейнеров (тесты, CHANGELOG/docs, push, PR,
make deploy). - CI: CodeQL — workflow
.github/workflows/codeql.yml(Pythonapp/web+app/processor, TypeScriptapp/ui/src), конфиги.github/codeql/; доки CODEQL / RU, пункты в mkdocs и SITE_MAP; рекомендация расширения GitHub.vscode-codeql в.vscode/extensions.json; скриптscripts/codeql-local.sh;.gitignore:.tools/(локальный CLI, БД, SARIF); в доке — пример triage последнего локального прогона. - #82: на странице видео — кнопки «предыдущий / следующий» ролик за тот же календарный день UTC, что и
start_time; APIGET /api/ui/videos/:id/neighbors(previous_id,next_id,index,total,day_utc). - Скрипт
scripts/github-project-mark-done.sh— пометить issue на доске BirdLense Hub — Roadmap как Done (поля Status и Поток); см. CONTRIBUTING. - Примеры алертинга Prometheus:
examples/prometheus/birdlense.rules.yml,examples/prometheus/alertmanager.birdlense.example.yml; раздел Alerting в CONFIGURATION / RU — закрывает #57. app/ui/package.json: полеengines(Node 22.x, минимум 22.13; npm >=10) — согласовано с CI и UI Docker stage..vscode/extensions.json— рекомендуемые расширения (ESLint, Prettier, Docker).- CI: workflow
E2E (Playwright)(.github/workflows/e2e-scheduled.yml) — раз в неделю +workflow_dispatch; не required в ruleset. - CI: job
docker-tests— сборка образаbirdlense+make test+make test-webна каждый PR/push вmainиdev(см. TESTING); в ruleset Protect наmainrequired checks:ui-build,docs,docker-tests. - Скрипты GitHub Project:
scripts/github-project-pat-hint.sh, загрузкаscripts/.env.project, шаблонscripts/env.project.example— classic PAT вместо OAuth refresh (без круга device-login). - Roadmap: секция Backlog consilium (March 2026) + 11 активных GitHub Issues #46–#48, #50–#57 для доски Project (#49 ARM — вне скоупа).
- CI: workflow
prune-branches.yml— опционально, толькоworkflow_dispatch: снятие сoriginветок кромеmainиdev(без cron; обычная уборка — после merge PR). - Скрипт
scripts/github-project-add-backlog-consilium.sh— добавить issues #46–#57 на доску Project, с пропуском #49 по умолчанию (GITHUB_BACKLOG_SKIP_ISSUES; нужен scopeprojectуgh). .github/github-social-preview.png— Open Graph / Social preview для репозитория (1280×640).
- Репозиторий: расширена документация и шаблоны локального деплоя; в
.gitignoreпо-прежнему не коммитятся персональные локальные файлы редактора и секреты. - CI: CodeQL —
github/codeql-actionv3 → v4 (changelog GitHub): без предупреждений о Node 20 и deprecation v3 на раннере. - Доки CodeQL (EN/RU):
workflow_dispatch, codeql-action@v4 в вводном абзаце; установка расширения в VS Code (CLI, VSIX, IDGitHub.vscode-codeql)..vscode/extensions.json— тот же ID издателя. - ROADMAP (EN/RU): бэклог оператора — issues #80 (галерея), #81 (коррекция видов Unknowns ↔ видео), #82 (навигация по видео); карточки на Project BirdLense Hub — Roadmap.
- Безопасность #46: rate limit
POST /api/ui/settings/verify-password— IP клиента за nginx (client_ip_for_rate_limit:X-Real-IP,X-Forwarded-For; nginx передаёт оба для/apiи/metrics), сброс счётчика при успешном входе,Retry-Afterпри 429; pytestTestVerifyPasswordRateLimit; доки ACCESS_CONTROL / API / SECURITY / TESTING / OPEN_SOURCE_PREP / ROADMAP. - Политика платформы: официально только x86/amd64 (Intel/AMD); ARM / aarch64 не поддерживаются и не планируются — ROADMAP, доки, конфиг; бэклог без ARM64 Docker (#49).
- ROADMAP (EN/RU): триаж Issue vs Discussion; Future work candidates (a11y, E2E, секреты, версии стека, community/donation UX); таблица идей переименована в Shipped ideas (archive); UX-блок выровнен; ACCESS_CONTROL ссылается на кандидатов.
chore(deps): @mui/x-charts 7.x → 8.x вapp/ui(#42)..gitignore:app/data/processor.log*— ротированные логи процессора не коммитятся.- GitHub: модель веток — фича → PR в
dev, затем PRdev→main; CONTRIBUTING + шаблон PR;delete_branch_on_merge=true(фичи не копятся,main/devзащищены от удаления).github-repo-bootstrap.shи GITHUB_SETUP_GH.ru.md §4 обновлены. - Доки: INSTALL ↔
scripts/deploy.sh(контейнерbirdlense,DEPLOY_REMOTE_DIR, rsync, Intel override, исключение.tools/); примерdeploy.local.sh.exampleсDEPLOY_REMOTE_DIR; SCENARIOS.ru (Grafana) как в EN; OPEN_SOURCE_PREP.ru — актуальный блок про плейсхолдеры; README / I18N_STATUS / SITE_MAP — формулировки под MkDocs; пути клонBirdLense-Hubvs каталог на сервере. app/Makefile: комментарии деплоя и E2E без захардкоженного LAN IP.- GitHub: ruleset Protect на default branch — обязательны успешные checks
ui-buildиdocs(workflow CI); approvals по-прежнему 0 (solo). - Dependabot — не больше одного открытого PR на блок (
open-pull-requests-limit: 1). - Локально: remote
upstreamк стороннему репозиторию не используется (репозиторий на GitHub — не форк). - Доки: LOCAL_DEV / RU — Node 22 (nvm/fnm/Volta), WSL / VS Code, Python 3.11 (приложение) vs 3.12 (MkDocs), venv для доков, чеклист перед релизом; TESTING / RU — предупреждение про RAM и OOM при
make test, workflow E2E по расписанию; Documentation / RU — явное разделение Python для MkDocs и runtime; CONTRIBUTING / RU — PR: полный набор тестов; README / RU — блок Developers.
0.2.5 - 2026-03-23
- #81 (фаза B): на странице Неизвестные после успешной коррекции вида или «Верно» — в уведомлении действие «Открыть видео» (по умолчанию остаётесь в списке; при наличии
video_idsnackbar дольше открыт). См. UX_UNKNOWN_VIDEO_CORRECTION.
0.2.4 - 2026-03-22
- #80 (галерея): фоновая загрузка кадров после
POST /api/processor/videosвыполняется внутри Flask app context — иначе SQLAlchemy не видел сессию и загрузки не происходили. Логи:Gallery upload thread failedпри прочих ошибках. - Web Push:
notify_app_startupвызываетnotify()внутри app context — устранено предупреждениеWorking outside of application contextпри старте, если включены push и есть подписки.
- Тесты
app/web/tests/test_gallery_upload.py; смок галереи в TESTING §2.6 / TESTING.ru §8; troubleshooting в CONFIGURATION → Gallery. - Спецификация UX #81: UX_UNKNOWN_VIDEO_CORRECTION; фаза A: подсказки в справке Unknowns / Video details (i18n EN/RU).
0.2.3 - 2026-03-20
- GitHub: Discussions/Issues/labels/milestones; скрипты bootstrap/import для Project (опционально).
- CI: PR — сборка UI + strict MkDocs; Redoc для OpenAPI в
docs/reference/. - Docs:
SHORT_DESCRIPTIONEN/RU;app/READMEEN/RU.
- Обновлены версии GitHub Actions (checkout, setup-, upload-, Docker).
- Pages и Docker: корректные триггеры на published Release (
latest, деплой сайта). - MkDocs: баннер и версия в шапке от
VERSION/extra.site_version; ROADMAP EN без ложного бэклога; strict — внешние ссылки на blob.
- Документация: статический сайт (MkDocs + GitHub Pages), карта и i18n; отчёт Wiki report в Actions (Summary, артефакт, опционально push в GitHub Wiki).
- Сообщество:
GOVERNANCE,CODEOWNERS, шаблон PR; инструкция настройки репозитория черезgh(GITHUB_SETUP_GH);WIKI_AUTOMATION; черновик материала вdocs/article/habr.md.
- npm (UI): обновлена транзитивная зависимость
flatted(GHSA high / prototype pollution).
- Push в GitHub Wiki: проверка
has_wiki, понятные ошибки; bootstrap без флага--disable-wikiв старых версияхgh.
- В bootstrap репозитория Wiki включается через API (
has_wiki=true).
- Prometheus /api/metrics — эндпоинт для Grafana (CPU, память, диск, GPU, detections, species, videos).
- Intel GPU метрики — карточка GPU в System,
gpu_percentиз sysfs/intel_gpu_top.
- Документация — консолидация: TROUBLESHOOTING в один файл, MQTT/Gallery/Detection в CONFIGURATION, INSTALL+DEPLOYMENT+DEPLOY_USER в INSTALL, TRAINING+HUGGINGFACE в TRAINING. Удалены дубли, архив сокращён.
- Подсказка кодирования — убрано «(NUC, Celeron и др.)» из UI.
0.2.0 - 2026-03-18
- Публичная галерея — тестовый контейнер
docker/gallery-testдля проверки загрузки кадров. - Порог бинарного детектора — настраиваемый
processor.min_confidence_binary(по умолчанию 0.25) для снижения ложных срабатываний. - PWA: prompt при обновлении — Snackbar «Доступна новая версия» вместо автоматической перезагрузки.
- Пороги детекции — повышены по умолчанию:
min_confidence_to_process0.15,min_track_duration3 сек,min_confidence_to_store0.10. - Шрифты — Google Fonts загружаются асинхронно (не блокируют рендер, быстрее в РФ).
- Telegram — retry, увеличенный timeout, fallback на текст при ошибке фото, сжатие изображений.
0.1.10 - 2026-03-17
- Overview — grid вместо flex для Feed+Chart (стабильный layout при логине).
- FeedCard — подсказка «Кнопка доступна администратору. Волонтёры могут помочь с видами» вместо «Введите пароль настроек».
- ProtectedRoute — универсальное сообщение «Введите пароль администратора для доступа к этому разделу» для Settings, System, Library.
- Ограничения для не залогиненных — PDF-отчёт, экспорт (CSV/JSON/eBird/Dataset), изменение корма в кормушке доступны только после входа (admin или contributor для экспорта; admin для корма).
0.1.9 - 2026-03-17
- Карточка «Сравнение с регионом» — показ списков видов: ваши виды в топе региона и полный топ региона по eBird.
- Unknowns — выбор даты и времени суток как в Записях (DatePicker + Утро/День/Вечер/Ночь вместо прокрутки по часам).
- timeUtils — общий
getTimeRangeдля Timeline и Unknowns.
0.1.8 - 2026-03-17
- Unknowns — подсказка про выбор часа — при выборе времени (не 00:00) показываются только детекции за выбранный час.
- E2E smoke-тесты — Overview, Timeline, Unknowns, System.
- Unknowns — убрано дублирование заголовка и описания (остаётся только PageHelp).
- PDF-отчёт — брендинг BirdLense Hub, шапка/футер на каждой странице, Executive Summary, секция «About this report».
- Зависимости — @mui/system для сборки, keyframes из @emotion/react.
0.1.7 - 2026-03-16
- «Применить ко всем в видео» — массовая коррекция: выбрать вид и объединить все детекции в одном видео (удобно при разных нейросетях или прерываниях).
- «Исправить счётчики» — Система → Управление хранилищем: удаляет осиротевшие визиты и синхронизирует species_id. Исправляет некорректные счётчики в календаре и каталоге после коррекций.
- Навигация — короткие подписи: «Миграции», «Каталог», «Food», «Species».
- Календарь миграций — убрано дублирование заголовка (остаётся только PageHelp).
- TG-фото — отправка через base64 вместо пути к файлу (надёжнее при любом деплое).
- Инвалидация кэша — при коррекции видов обновляются migration-calendar, bird-directory, species, speciesSummary.
- Счётчики после коррекции — календарь миграций и каталог птиц теперь обновляются при исправлении видов.
0.1.6 - 2026-03-16
- Кнопка «Скачать видео» — только для админа и помощника (contributor_or_admin_access), после ввода пароля.
- TG-превью best frame — в уведомлениях Telegram отправляется фото лучшего кадра детекции.
- Секреты в production — FLASK_SECRET_KEY, PROCESSOR_SECRET, BIRDLENSE_ENV задаются через deploy.local.sh и записываются в app/.env на сервере.
- deploy.sh — запись секретов без дубликатов (grep -v -E).
- image_path — валидация _is_safe_image_path перед отправкой в Telegram.
0.1.5 - 2026-03-15
- lastDetection по end_time — виджет «Последняя птица» показывает последнее по времени наблюдение (order_by end_time), не первое.
- Bird = неопределённый объект — «Bird»/«bird» без вида не считается в overview (топ, статистика), всегда в Unknowns.
- MQTT merge по timestamp — MQTT-события используют реальное время (не растягивают на всё видео).
- Унификация окон merge — visit_timeout = dedup_window_seconds (45 сек по умолчанию).
- Code review fixes —
datetime.now()→ UTC в Overview и activity;logger.warn→logger.warning;request.json or {}в purge_storage; валидацияspecies_id(int). - Race при регенерации — блокировка повторного запуска (409 если уже running).
- Path traversal — проверка формата video_path в detection_crop_service.
- parse_utc_timestamp — утилита для парсинга timestamp.
- get_primary_video_for_visit, format_visit_for_timeline — хелперы для timeline.
- overview_service — вынос логики Overview в сервис.
- species_summary_service — вынос логики species summary в сервис.
- Константы — LOG_LINES_DEFAULT/MAX, UNKNOWNS_LIMIT_MAX.
- API.md — добавлены dataset/export, push/*, статус unknown.
- Роли доступа — два пароля:
settings_password(Admin),contributor_password(помощник). Contributor: коррекция видов, iNaturalist, отчёты, экспорт датасета. Admin: кормушка, настройки, система. Документ ACCESS_CONTROL.md. - Датасет из лучших кадров — сохранение best_frame в
data/dataset/train/<Species>/для экспорта и дообучения. Конфигprocessor.save_dataset_crops: true,processor.dataset_min_confidence(по умолчанию 0.5). APIGET /api/ui/dataset/export— ZIP с train/val и dataset_info.json. Кнопка «Экспорт датасета» в Система → Управление хранилищем. При коррекции вида в Unknowns/VideoDetails файл перемещается в директорию нового вида.
- Кормушка — кнопка «Выдать корм» защищена паролем Admin. Без разблокировки кнопка неактивна.
- Экспорт датасета — доступен в Timeline (для Contributor) и в Система (для Admin).
0.1.4 - 2026-03-15
- eBird export — экспорт списка видов в формате eBird Record для импорта в eBird.org. Кнопка «Экспорт для eBird» в Timeline. Настройки: Настройки → Расширенные (страна, регион, локация).
- Confidence по виду — пороги
min_confidenceпо видам. Редкие виды — ниже порог. Конфигprocessor.species_confidence_overrides: {"Species Name": 0.05}. Настройки → Processor. - Экспорт в iNaturalist — кнопка «Отправить в iNaturalist» на карточке детекции (Timeline) и на странице видео. Скачивает кадр из видео и открывает inaturalist.org/observations/upload. API:
GET /api/ui/detections/:id/crop.
- Timeline — выбор даты + время суток вместо дата+час. DatePicker без прокрутки по часам. Добавлена Ночь (22–06) для ночных птиц.
0.1.3 - 2026-03-15
- Prometheus метрики — эндпоинт
GET /metricsв формате Prometheus:birdlense_detections_total,birdlense_species_count,birdlense_videos_total. Для Grafana и дашбордов. - «Неизвестные» — страница
/unknownsсо списком детекций с низкой confidence (< порога). Ручная проверка и исправление вида. Порог настраивается в Настройках → Расширенные или в конфигеui.unknown_confidence_threshold(по умолчанию 0.5). - PDF-отчёт — месячный отчёт: N видов, топ-5, графики. Кнопка «PDF-отчёт» на Overview. API:
GET /api/ui/report/pdf?month=YYYY-MM. - Bird song player (Xeno-canto) — кнопка «Воспроизвести песню» на странице вида. API v3, ключ в Настройки → Расширенные. Fallback: ссылка на поиск xeno-canto.org при отсутствии ключа. API:
GET /api/ui/species/:id/xeno-canto.
0.1.2 - 2026-03-14
- Playback speed (0.5x, 2x) — кнопки в видеоплеере для замедления/ускорения просмотра.
- Виджет «Последняя птица» — блок на Overview с последней детекцией дня (время и вид).
- CSV/JSON экспорт — кнопка экспорта в Timeline: скачать визиты за выбранный период в CSV или JSON.
- Фильтр по времени суток — в Timeline: Утро (6–10), День, Вечер (18–22).
- Webhook — POST при каждой детекции на настраиваемый URL (Настройки). JSON: species, confidence, time, source.
- PWA — vite-plugin-pwa: service worker, offline cache, install prompt «Добавить на главный экран».
0.1.1 - 2026-03-14
- Источник распознавания в UI — полосы и карточки показывают YOLO, Frigate или BirdNET. Документация:
docs/user/features.md(таблица Detection source). - deploy.sh — rsync вместо tar|ssh; автоустановка rsync на сервере; повторы при сбое (SYNC_RETRIES=3, BUILD_RETRIES=2).
- Консолидация детекций —
min_confidence_to_process: 0.03 → 0.10,min_track_duration: 1 → 2 сек. Меньше ложных срабатываний. - Рефакторинг — удалён мёртвый код
useMockDataв api.tsx; фильтрация камер вынесена вapp_config/cameras.py; E2E-хелперы вe2e/helpers/settings.ts. - merge_detections — реализован
dedup_window_seconds: детекции одного вида с разрывом > 45 сек считаются разными визитами. - _canonical_key — нормализация имён с underscore (
Great_Tit,Parus major (Great Tit)→ один ключ для слияния). - birdnet_local — заменён на
birdnet_mqtt(audio_detections всегда пустой).legacyоставлен для импорта старых записей.
- mocks.tsx — не использовался.
- deploy-to-server.sh — заменён на
make deploy.
- deploy.sh — защита от повреждения
.env: при размере > 1 MB файл заменяется на.env.example. - SIGPIPE при деплое — rsync устойчивее к обрывам, чем tar|ssh.
0.1.0 - 2026-03-12
Первый стабильный релиз (без alpha/beta).
- Telegram-уведомления — бот отправляет сообщения в канал или чат. Настройки: токен бота, chat_id, base_url для ссылок.
- Telegram Bot API 9.4/9.5 — кнопки с эмодзи и стилем (primary), динамическое время
<tg-time format="r">, опцияlink_preview_largeдля больших превью ссылок. - sendPhoto — при
processor.save_images: trueотправляется фото детекции в Telegram. - sendPaidMedia — раздельные настройки: Stars за просмотр (0–25000) и за пересылку/копирование.
- Уведомления — отправляются после слияния (YOLO + Frigate/BirdNET), а не по первому результату YOLO. Один результат на вид.
- merge_detections — один результат на вид (max confidence, объединённый интервал). Дедупликация YOLO-треков и MQTT-событий.
- Уведомления — ntfy заменён на Telegram Bot API.
- ntfy — убран из nginx (порт 8081), deploy.sh, UI.
- Защита по паролю — единая точка входа при нажатии на иконку шестерёнки.
- Картинки птиц (Wikipedia) — resolveImageUrl() для абсолютных и относительных URL.
- PROCESSOR_SECRET — корректная запись в deploy.sh (printf).
- Деплой — env_file, health check, .env.example при первом деплое.
- Processor API — timeout 30s, retry при 5xx.
- VideoPlayer — сброс view при смене видео без спектрограммы.
- MQTT — reconnect при обрыве.
- Конфиг — валидация YAML, fallback на пустой dict.
0.1.0-beta.2 - 2026-03-11
- Heartbeat — устойчивый retry при ошибках, логирование 403 при неверном PROCESSOR_SECRET
- Status icons — цвета (ok=зелёный, unknown=amber)
- E2E — baseURL по умолчанию localhost:8085
- Docs — европейские птицы, датасеты
0.1.0-beta.1 - 2026-03-10
- Coverage — pytest-cov,
make test-coverage,make test-report - PROCESSOR_SECRET — автогенерация при деплое
- util.py — путь к
hierarchy_names.txtчерез__file__ - Makefile — volume для test (локальный код)
- CPU temperature — убрана из метрик
- Orphan containers — удалены старые контейнеры
- Web API тесты — путь к seed/hierarchy_names.txt
Первый альфа-релиз.