chore: release v0.2.4
Release / release (push) Successful in 1m18s

This commit is contained in:
2026-04-22 15:36:08 +03:00
parent 2be608ba95
commit 93df538819
4 changed files with 30 additions and 20 deletions
+27 -17
View File
@@ -1,32 +1,42 @@
## v0.2.3 (2026-04-22)
## v0.2.4 (2026-04-22)
Bot-command scope hardening: commands now see only what their chat is wired to
receive notifications about, closing a leak where a bot serving multiple chats
exposed the whole provider catalog to every chat. Plus a handful of Immich
command fixes (missing `public_url` enrichment, silently-swallowed search errors,
always-on link previews).
Telegram media cache rebuilt around **thumbhash validation** — asset cache
entries now invalidate when the visual content changes, not after a fixed
TTL — plus a settings-page overhaul (cache stats, clear button, timezone /
locale pickers) and full mobile-nav parity with the desktop sidebar.
### Features
- **Per-chat album scope derived from notification routing** — for a `(provider, bot, chat_id)` triple, the allowed album set is now computed by walking `TargetReceiver → NotificationTarget → NotificationTrackerTarget → NotificationTracker` and unioning the collection IDs. `/albums`, `/random`, `/search`, `/find`, `/latest`, `/memory`, `/summary`, `/favorites`, `/place`, `/person`, `/status`, `/events` all intersect their results with the resolved scope. Chats with no notification routing for a tracker return nothing rather than leaking the provider's catalog. ([3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09))
- **Scope modal relabeled** — the per-listener `allowed_album_ids` UI is now explicitly an *override for this bot* (escape hatch when you want a divergent scope for a whole bot); the default is *derive from notification routing*, which matches what operators have already configured elsewhere. ([3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09))
- **Drop tracker counts from `/status`** — `trackers_active` / `trackers_total` were per-provider aggregates that would leak info about trackers a chat has no visibility into. Immich default `/status` templates (en, ru) now show only *Albums* + *Last event*; the template-editor variable catalog no longer suggests the removed vars for the Immich `/status` slot. **Note:** custom templates that reference `{{ trackers_active }}` / `{{ trackers_total }}` need to be updated. ([5a232f1](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/5a232f1))
#### Telegram media cache
- **Thumbhash-validated asset cache** — dispatcher builds an `asset.id → thumbhash` resolver from `event.added_assets` (Immich already populates `thumbhash` in `extra`) and passes it to `TelegramClient`. Asset-cache entries now invalidate on visual change rather than age. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
- **Configurable cache cap & stats** — `TelegramFileCache` gets a `max_entries` LRU cap (applies in both TTL and thumbhash modes), `ttl_seconds <= 0` disables TTL entirely, and a `stats()` method exposes per-bucket counts / sizes / oldest+newest timestamps. New settings: `telegram_asset_cache_max_entries` (default 5000); `telegram_cache_ttl_hours` default bumped `48 → 720` (30 days) and is now URL-only. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
- **Cache admin endpoints** — `GET /settings/telegram-cache/stats` and `POST /settings/telegram-cache/clear`. `PUT /settings` now soft-resets the in-memory caches when cache-shaping keys change (on-disk `file_id`s preserved). ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
#### Settings page
- **Cache stats card** — per-bucket (URL / asset) counts, cumulative uploaded-to-Telegram byte size, oldest/newest timestamps, and a hint explaining what the size means. Clear-cache button behind a confirm modal. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
- **New `TimezoneSelector` and `LocaleSelector` components** replace the raw inputs with IANA-aware searchable pickers. Max-entries input exposed; TTL range widened to `0..8760` hours (`0` = disabled). ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
#### Mobile nav
- **Full sidebar parity in the *More* panel** — now mirrors the desktop sidebar tree (groups + subnodes) so every destination is reachable from mobile. Previously the panel carried a hand-picked flat list that drifted behind newly-added routes. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
- **Safe-area handling** — nav height uses `env(safe-area-inset-bottom)`; panel bottom + `z-index` fixed so page content can no longer visually overlay the bottom bar. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
### Bug Fixes
- **`/albums` honors per-chat scope** — previously ignored `CommandTrackerListener.allowed_album_ids` and listed every album tracked by the provider, so scoped chats saw neighbours' albums. Now applies the same intersect filter the `/_cmd_immich` media commands use. ([4ff3876](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/4ff3876))
- **Disable Telegram link previews on command text replies** — listings (`/albums`, `/events`, `/people`, …) embed multiple links and were rendering a preview for the first URL regardless of the operator's *Disable link previews* toggle. `send_reply` now always passes `disable_web_page_preview=True`. ([4ff3876](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/4ff3876))
- **Restore `public_url` enrichment on `/search`, `/find`, `/person`, `/place`** — `_enrich_assets`'s return value was being discarded, dropping the public URL populated on each asset. Now assigned properly. ([3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09))
- **Surface Immich search errors instead of silently returning `[]`** — `search_smart` / `search_metadata` consolidated into a `_search_items` helper that logs non-200 responses and transport errors, and accepts the alternate `{"assets": [...]}` flat-list shape from older Immich versions. "Always no results" bugs are now diagnosable. ([3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09))
- **Redact Immich search error bodies** before they land in server logs — credentials echoed by authenticating proxies no longer leak into logs. ([3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09))
- **`update_settings` TypeError** — `any(await ... for ...)` was an async generator (not an iterator) and raised at runtime; replaced with an explicit loop so settings updates actually commit. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
### Accessibility
- **Password-manager association** on the password-change form — hidden `username` field + `autocomplete` hints on all three password inputs so browsers stop warning and password managers fill correctly. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
- **Telegram webhook secret** wrapped in a no-op form with `autocomplete=off` to silence DOM/a11y warnings. ([2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b))
---
<details>
<summary>All Commits</summary>
- [5a232f1](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/5a232f1) — feat(commands): drop tracker counts from /status *(alexei.dolgolyov)*
- [4ff3876](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/4ff3876) — fix(commands): /albums honors per-chat scope, disable link previews *(alexei.dolgolyov)*
- [3b76a09](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/3b76a09) — feat(commands): per-chat album scope derived from notification routing *(alexei.dolgolyov)*
- [2be608b](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/2be608b) — feat(cache): thumbhash-validated asset cache + settings UX overhaul *(alexei.dolgolyov)*
</details>
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "notify-bridge-frontend",
"private": true,
"version": "0.2.3",
"version": "0.2.4",
"type": "module",
"scripts": {
"dev": "vite dev",
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "notify-bridge-core"
version = "0.2.3"
version = "0.2.4"
description = "Core library for Notify Bridge — service provider abstractions, models, notifications, and templates"
requires-python = ">=3.12"
dependencies = [
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "notify-bridge-server"
version = "0.2.3"
version = "0.2.4"
description = "Standalone Notify Bridge server — FastAPI REST API with SQLite database"
requires-python = ">=3.12"
dependencies = [