• v0.6.3 0e675c4b38

    Notify Bridge 0.6.3
    Release / release (push) Successful in 1m15s
    Stable

    alexei.dolgolyov released this 2026-04-27 15:42:04 +03:00 | 39 commits to master since this release

    v0.6.3 (2026-04-27)

    Adds user filters for the Gitea tracker, makes the dashboard navigable, removes leftover webhook polling, and fixes the theme/sidebar flash on hard reload.

    User-facing changes

    Features

    • Gitea — sender filters: NotificationTracker now exposes sender_allowlist and sender_blocklist via MultiEntitySelect. The picker is populated from Gitea /users/search merged with past EventLog senders, so it is useful even before the first webhook arrives (42af7a6)
    • Dashboard navigability: stat cards are now <a> links that route to providers, trackers, targets, command-trackers, or scroll to the events panel. Provider deck rows highlight the target provider on click (42af7a6)
    • Command trackers / configs: auto-reselect the matching config when the provider type changes, matching notification-tracker behaviour (42af7a6)
    • Webhook providers (gitea, planka, webhook): stop scheduling interval polling jobs on tracker create/update/startup, and hide the misleading "every Xs" indicator in the tracker list — webhook trackers do not poll (42af7a6)

    Bug Fixes

    • Theme FOUC on hard reload: an inline blocking script in app.html now resolves the theme from localStorage (or prefers-color-scheme) and sets data-theme on <html> before first paint, eliminating the dark→light flash users saw when the light theme was selected (b107b01)
    • Sidebar jump on reload: sidebar collapsed state and expanded nav groups now hydrate synchronously in their $state initialisers instead of inside onMount, so the sidebar no longer snaps from expanded→collapsed and groups no longer slide open after mount (b107b01)
    • Provider-filter row pop-in: the global provider-filter row now stays rendered while providersCache.fetchedAt === 0, so it no longer pops in mid-paint and pushes the nav down once the cache resolves (b107b01)

    Development / Internal

    Build

    • Build-time app version: vite.config.ts now reads frontend/package.json and exposes its version as an __APP_VERSION__ global via Vite's define, with an ambient declaration in app.d.ts so the layout's brand version badge type-checks (4307955)

    Database

    • Migration: drop legacy batch_duration column from notification_tracker — the field had been removed from the model but its NOT NULL constraint still blocked inserts on older DBs (42af7a6)

    Documentation

    • Refresh .claude/docs/entity-relationships.md with current NotificationTracker fields (filters, adaptive_max_skip, default_*_config_id) (42af7a6)

    All Commits
    Hash Message Author
    4307955 feat(frontend): inject __APP_VERSION__ from package.json at build time alexei.dolgolyov
    b107b01 fix(redesign): prevent theme FOUC and sidebar jump on hard reload alexei.dolgolyov
    42af7a6 feat(trackers): user filters for Gitea, webhook polling cleanup, dashboard navigability alexei.dolgolyov

    Changelog

    0e675c4 chore: release v0.6.3
    4307955 feat(frontend): inject APP_VERSION from package.json at build time
    b107b01 fix(redesign): prevent theme FOUC and sidebar jump on hard reload
    42af7a6 feat(trackers): user filters for Gitea, webhook polling cleanup, dashboard navigability

    Downloads
  • v0.6.2 c43dc598a1

    Notify Bridge 0.6.2
    Release / release (push) Successful in 1m39s
    Stable

    alexei.dolgolyov released this 2026-04-27 14:29:44 +03:00 | 43 commits to master since this release

    v0.6.2 (2026-04-27)

    Polishing pass on locale and timezone pickers in the redesigned UI: editors and selectors now use the same EntitySelect palette pattern, and the timezone dropdown is portalled to escape Card clipping.

    User-facing changes

    Bug Fixes

    • Template editors (notification & command) now use EntitySelect for locale switching and default to the configured primary locale when opening, editing, or cloning a config (previously always defaulted to en) (1bfec52)
    • LocaleSelector add-flow now uses EntitySelect for catalog pick; custom BCP-47 codes (e.g. de-CH) keep a small dedicated input (1bfec52)
    • TimezoneSelector dropdown was being clipped by Card's overflow: hidden and backdrop-filter; portalled to <body> with an overlay backdrop and styled as a centered modal palette (same pattern as EntitySelect) (1bfec52)
    • Removed top padding on the timezone scroll list so sticky region group headers no longer leak rows above them (1bfec52)

    Development / Internal

    Refactoring

    • Extracted shared locale catalog to frontend/src/lib/locales.ts for reuse across selectors (1bfec52)

    Changelog

    c43dc59 chore: release v0.6.2
    1bfec52 fix(redesign): EntitySelect for language pickers + portal Timezone picker

    Downloads
  • v0.6.1 b320090a56

    Notify Bridge 0.6.1
    Release / release (push) Successful in 3m17s
    Stable

    alexei.dolgolyov released this 2026-04-25 15:25:23 +03:00 | 45 commits to master since this release

    v0.6.1 (2026-04-25)

    Small visual follow-up to the Aurora redesign: the Active Wires pipe on the dashboard now reads more prominently.

    User-facing changes

    Bug Fixes

    • Make Active Wires pipe visually prominent (cc8d961)

    Changelog

    b320090 chore: release v0.6.1
    cc8d961 fix(redesign): make Active Wires pipe visually prominent

    Downloads
  • v0.6.0 9eb478fdc9

    Notify Bridge 0.6.0
    Release / release (push) Successful in 1m25s
    Stable

    alexei.dolgolyov released this 2026-04-25 14:54:16 +03:00 | 47 commits to master since this release

    v0.6.0 (2026-04-25)

    This release ships the Aurora redesign of the frontend — a glass-and-tokens visual language applied across the dashboard, sidebar, page headers, and overlays — together with per-chat command localization for the Telegram bot.

    User-facing changes

    Features

    Frontend — Aurora redesign

    • Aurora foundation: design tokens, glass sidebar, redesigned dashboard (d9ef3c6)
    • Project mockup richness onto the live dashboard (d3210fd)
    • Subpage hero header, IconPicker portal, tighter gaps (9733e5c)
    • Roll subpage hero across all pages, plus Aurora Button, JinjaEditor, and pulse fix (d662b50)
    • Stack PageHeader meter top-right, action button bottom-right (9643fe5)
    • Collapsible dashboard sections + glass mobile-more sheet (9eb76c1)

    Telegram

    • Per-chat command localization with a unified locale resolver (ef942b7)

    Bug Fixes

    • Portal IconGridSelect popup + snap navbar to mockup (0105d9f)
    • Brand snap, event sentences, palette glass, full-width layouts (1895c5e)
    • Align topbar horizontal padding with page content (46a4a6e)
    • Portal overlays + solid popup surfaces for legibility (d356e5a)
    • A11y, mobile, and perf polish for production push (711f218)

    Development / Internal

    Chores

    • Add Aurora redesign mockups + chooser under design-mockups/ (1e35724)
    All Commits
    Hash Message Author
    ef942b7 feat(telegram): per-chat command localization + unified locale resolver alexei.dolgolyov
    711f218 fix(redesign): a11y, mobile, perf polish for production push alexei.dolgolyov
    9eb76c1 feat(redesign): collapsible dashboard sections + glass mobile-more sheet alexei.dolgolyov
    d356e5a fix(redesign): portal overlays + solid popup surfaces for legibility alexei.dolgolyov
    9643fe5 feat(redesign): stack PageHeader meter top-right, button bottom-right alexei.dolgolyov
    d662b50 feat(redesign): roll subpage hero across all pages + Aurora Button + JinjaEditor + pulse fix alexei.dolgolyov
    9733e5c feat(redesign): subpage hero header + iconpicker portal + tighter gaps alexei.dolgolyov
    46a4a6e fix(redesign): align topbar horizontal padding with page content alexei.dolgolyov
    1895c5e fix(redesign): brand snap, event sentences, palette glass, full width alexei.dolgolyov
    0105d9f fix(redesign): portal IconGridSelect popup + snap navbar to mockup alexei.dolgolyov
    d3210fd feat(redesign): project mockup richness onto live dashboard alexei.dolgolyov
    d9ef3c6 feat(redesign): aurora foundation — tokens, glass sidebar, dashboard alexei.dolgolyov
    1e35724 chore(design): add aurora redesign mockups + chooser alexei.dolgolyov

    Changelog

    9eb478f chore: release v0.6.0
    ef942b7 feat(telegram): per-chat command localization + unified locale resolver
    711f218 fix(redesign): a11y, mobile, perf polish for production push
    9eb76c1 feat(redesign): collapsible dashboard sections + glass mobile-more sheet
    d356e5a fix(redesign): portal overlays + solid popup surfaces for legibility
    9643fe5 feat(redesign): stack PageHeader meter top-right, button bottom-right
    d662b50 feat(redesign): roll subpage hero across all pages + Aurora Button + JinjaEditor + pulse fix
    9733e5c feat(redesign): subpage hero header + iconpicker portal + tighter gaps
    46a4a6e fix(redesign): align topbar horizontal padding with page content
    1895c5e fix(redesign): brand snap, event sentences, palette glass, full width
    0105d9f fix(redesign): portal IconGridSelect popup + snap navbar to mockup
    d3210fd feat(redesign): project mockup richness onto live dashboard
    d9ef3c6 feat(redesign): aurora foundation — tokens, glass sidebar, dashboard
    1e35724 chore(design): add aurora redesign mockups + chooser

    Downloads
  • v0.5.2 770c198ac3

    Notify Bridge 0.5.2
    Release / release (push) Successful in 1m48s
    Stable

    alexei.dolgolyov released this 2026-04-24 21:58:40 +03:00 | 61 commits to master since this release

    v0.5.2 (2026-04-24)

    Two related improvements to the notification-tracker stack: the display-filter fields on TrackingConfig (favorites-only, sort, max-assets, strip-tags, strip-asset-details) are now actually honored by every dispatch path — they previously existed in the model but were silently ignored on watcher / webhook / scheduled / memory / test fires. And the fixed batch_duration knob on NotificationTracker is replaced by a per-tracker adaptive_max_skip, so quiet trackers can opt into back-off without affecting busy ones.

    Features

    • Tracking-config display filters wired into every dispatch path — the filter fields on Immich TrackingConfig now apply consistently across watcher events, inbound webhooks, scheduled / periodic / memory cron fires, and manual test dispatch (ab621b6):
      • favorites_only drops events with no favorited new assets, or filters added_assets down to favorites only
      • assets_order_by / assets_order sort the rendered list (date / name / rating / random / none)
      • max_assets_to_show caps rendered + attached media (default raised from 5 → 10)
      • include_tags strips people from event extras and tags from each asset when disabled
      • include_asset_details strips city / country / state / lat / lon / is_favorite / rating / description when disabled — load-bearing fields (thumbhash, file_size, playback_size, cache keys) are preserved either way
      • New apply_tracking_display_filters helper in dispatch_helpers is the single source of truth
      • Targets sharing a TrackingConfig are dispatched together; targets with different configs each see their own shaped event
    • Per-tracker adaptive polling — replaces the global-feeling NotificationTracker.batch_duration with adaptive_max_skip, an opt-in cap on poll back-off (ab621b6):
      • NULL / 0 → disabled, every tick runs (previous default behavior preserved)
      • Positive N → caps the skip factor at (N-1)-in-N after a long idle stretch
      • Scheduler caches the cap in module state for the tick fast-path
      • Migration adds the new column; API schemas / responses, frontend types, i18n, and the tracker form are all updated to match

    Upgrade Notes

    • batch_durationadaptive_max_skip on NotificationTracker. The migration runs automatically; existing trackers default to disabled (every tick polls), matching previous behavior. Set a positive value per-tracker if you want quiet trackers to back off.
    • Default max_assets_to_show is now 10 (was 5). Existing tracking configs with a stored value are unaffected; only the default for newly created configs (or unset fields) changes. If you relied on the 5-asset implicit cap, set it explicitly.
    • Display filters now actually take effect. If you had configured favorites_only, include_tags, include_asset_details, etc. previously and expected them to do something — they will now. Review your tracking configs after upgrade if you don't want the filtering applied.

    All Commits
    Hash Message Author
    ab621b6 feat: wire tracking-config display filters + per-tracker adaptive polling alexei.dolgolyov

    Changelog

    770c198 chore: release v0.5.2
    ab621b6 feat: wire tracking-config display filters + per-tracker adaptive polling

    Downloads
  • v0.5.1 187b889c45

    Notify Bridge 0.5.1
    Release / release (push) Successful in 1m49s
    Stable

    alexei.dolgolyov released this 2026-04-24 19:21:39 +03:00 | 63 commits to master since this release

    v0.5.1 (2026-04-24)

    Extends the Immich scheduled/memory dispatch shipped in v0.5.0 with a per-album fan-out mode and rich multi-album templates, adds "Reset to default" tooling and an inline preview modal for notification / command templates, and introduces a none listener mode for Telegram bots (safer default for shared-token deployments). Also fixes an infinite-recursion bug in the notification dispatcher that was breaking test dispatch for periodic / scheduled / memory slots.

    Features

    • Per-album Immich dispatch for scheduled / memory slots — honors the new {kind}_collection_mode on TrackingConfig: per_collection fans out one event per album, combined pools assets as before. Combined mode now attaches album_name / album_url / album_public_url to each asset so templates can attribute rows to their source album. Default scheduled_assets and memory_mode templates render a multi-album header with an inline album list and per-row album link. The cron and test-dispatch paths now share a single build_immich_dispatch_events helper (b61394f).
    • "Reset to default" for template slots — new per-slot and whole-template reset buttons on notification and command template configs, backed by GET /*-template-configs/defaults endpoints. Confirmations use the app's ConfirmModal instead of window.confirm (b61394f).
    • Inline template preview + deep-link edit — tracking-configs "Preview template" now opens an inline preview modal with locale tabs instead of navigating away. The Edit button deep-links with ?edit_slot=<name> so the destination auto-opens the config and scrolls to the requested slot (b61394f).
    • Telegram bot none listener mode — third option alongside polling and webhook. Disables both long-polling and webhook delivery; useful when another instance owns the listener or the bot is send-only. Switching into none unschedules polling and unregisters the active webhook so Telegram stops delivering updates (be15463).

    Bug Fixes

    • Fix NotificationDispatcher._session_ctx infinite recursion when no shared aiohttp.ClientSession was passed — broke test dispatch for periodic / scheduled / memory slots (cron path was unaffected) (b61394f).
    • telegram-bots /chats/{id}/test now resolves chat.language_override / language_code instead of using the raw ?locale query param, matching the resolution the tracker-target test endpoint already used (b61394f).
    • Default scheduled_assets template no longer emits a blank line between the header and the first asset when the multi-album branch is taken (b61394f).

    Upgrade Notes

    • New Telegram bots default to none (safer when multiple bridges share a token). Existing bots upgraded from a pre-update_mode schema keep polling, so their behavior is unchanged. When creating a new bot, explicitly switch to polling or webhook if you want it to receive updates.
    • A new {kind}_collection_mode field was added to TrackingConfig for Immich scheduled/memory slots. Existing trackers keep the previous combined behavior by default; switch to per_collection per-tracker to opt in to one-event-per-album fan-out.

    All Commits
    Hash Message Author
    b61394f feat(immich): per-album scheduled/memory dispatch + template tooling alexei.dolgolyov
    be15463 feat(telegram): add 'none' listener mode for bots alexei.dolgolyov

    Changelog

    187b889 chore: release v0.5.1
    b61394f feat(immich): per-album scheduled/memory dispatch + template tooling
    be15463 feat(telegram): add 'none' listener mode for bots

    Downloads
  • v0.5.0 461fb495d7

    Notify Bridge 0.5.0
    Release / release (push) Successful in 1m10s
    Stable

    alexei.dolgolyov released this 2026-04-24 14:16:34 +03:00 | 66 commits to master since this release

    v0.5.0 (2026-04-24)

    A small but impactful release that finally makes the Immich scheduled / periodic / memory dispatch fire on its own. The slot was already visible in the tracker UI and the "Test" button worked — but no production scheduler was reading the config, so users only ever saw fires through manual tests. This release wires the missing cron jobs end-to-end.

    Features

    • Cron-fired Immich dispatch for scheduled / periodic / memory slots — adds the missing production fan-out so scheduled_enabled / scheduled_times (and the periodic / memory counterparts) on TrackingConfig actually fire on their own, not only through "Test" (309dec2):
      • New services/scheduled_dispatch.py reuses the test-path event builders, picks the slot template per kind (scheduled_assets / periodic_assets / memory_assets), and writes an EventLog row per fire so the dashboard reflects it.
      • services/scheduler.py gains _load_immich_dispatch_jobs, which builds one CronTrigger per (tracker, kind, HH:MM) from each tracker's default TrackingConfig, all keyed off the app-level IANA timezone. reschedule_immich_dispatch_jobs rebuilds the job set on any relevant CRUD or timezone change.
      • Tracker / link / tracking-config CRUD endpoints now invalidate the schedule, so edits take effect immediately without a restart.
      • Dispatch is skipped when scheduled / memory queries yield zero matching assets — prevents header-only "On this day:" spam when nothing qualifies.
      • EN / RU default scheduled_assets templates updated to surface that the delivery is a scheduled random selection.

    Upgrade Notes

    • No config changes required. Existing scheduled_enabled / scheduled_times / periodic_* / memory_* settings on tracking configs will start firing automatically on the next startup.
    • If you had been relying on the "Test" button as a workaround, you can stop doing that now.

    All Commits
    Hash Message Author
    309dec2 feat(immich): wire cron-fired scheduled/periodic/memory dispatch alexei.dolgolyov

    Changelog

    461fb49 chore: release v0.5.0
    309dec2 feat(immich): wire cron-fired scheduled/periodic/memory dispatch

    Downloads
  • v0.4.0 90def11b8d

    Notify Bridge 0.4.0
    Release / release (push) Successful in 1m3s
    Stable

    alexei.dolgolyov released this 2026-04-23 21:12:17 +03:00 | 68 commits to master since this release

    v0.4.0 (2026-04-23)

    A production-readiness release focused on hardening the service for real-world deployment: end-to-end structured logging with runtime controls, a broad security and runtime review across the HTTP, auth, DB, and scheduler layers, and a new pre-migration database snapshot that makes upgrades recoverable with a single file restore. Release CI and the Docker image build were also reworked for speed and reliability.

    Features

    • Production-grade logging with per-request correlation (request_id / command / chat_id / bot_id / dispatch_id), secret masking in both messages and tracebacks, JSON or text format, runtime log level + per-module overrides editable from the settings UI, and env-var boot overrides (NOTIFY_BRIDGE_LOG_LEVEL / _FORMAT / _LEVELS). Closes every silent drop in the Telegram send path — /random and media-group failures now log WARN / ERROR with full context instead of disappearing (f50d465)
    • Production-readiness hardening across security, async, DB, and ops (920920b):
      • Security: async SSRF-safe DNS resolver; allow_redirects=False on all outbound clients; Matrix homeserver_url validation; rejection of ***-masked secrets on provider / email-bot updates; bcrypt moved off the event loop; JWT iss / aud + leeway with strict claim rejection; setup TOCTOU closed inside a transaction; expanded rate limits; constant-time login; config rejects known dev secret keys and validates CORS / ports / token lifetimes; webhook bodies capped at 1 MiB; Discord 429 retries bounded; CSP + HSTS headers added.
      • Async / runtime: SQLite engine tuned (WAL, synchronous=NORMAL, foreign_keys=ON, busy timeout, pool pre-ping); ordered lifespan shutdown; shared aiohttp session race-free; blocking storage / backup writes offloaded to threads; NUT client timeouts; Telegram poller switched from 3 s short-poll to 30 s + 25 s long-poll (~10x fewer API calls).
      • Database: new performance-index migration covering every FK and hot-path composite; new schema_version table; __system__ placeholder user (id=0) seeded to satisfy FKs; list_notification_trackers rewritten from 1+N+N*M to batched loads; retention job extended to event / webhook / action-execution logs.
      • Scheduler: AsyncIOScheduler job defaults set (coalesce, misfire_grace_time=300, max_instances=1).
      • Ops: uvicorn runs with proxy_headers / forwarded_allow_ips / graceful shutdown timeout; access log suppressed outside debug; FastAPI version read from importlib.metadata; new /api/ready endpoint; docker-compose adds resource / PID limits, read_only + tmpfs, cap_drop: ALL, no-new-privileges, drops the ALLOW_PRIVATE_URLS=1 default, and points healthcheck at /api/ready.
      • Frontend: /login redirects already-authenticated users to / and shows a distinct "backend unreachable" banner (en / ru) when /auth/needs-setup fails.
    • Pre-migration SQLite snapshots via VACUUM INTO at lifespan startup — takes a consistent, atomic copy of the DB before migrations run, so a botched upgrade is recoverable by restoring a single file. Safe under WAL; best-effort (failures log but never raise); configurable via NOTIFY_BRIDGE_PRE_MIGRATE_SNAPSHOT_KEEP (default 5; 0 disables). Snapshots land in data_dir/backups/pre-migrate-<ts>.db and the N oldest are pruned each boot (7cbb02b)

    Bug Fixes

    • Allow unsafe-inline scripts in CSP so SvelteKit's hydration bootstrap inline <script> runs in production — without it the frontend failed to hydrate under the hardened CSP introduced in this release (8f0346e)

    Upgrade Notes

    • ALLOW_PRIVATE_URLS=1 is no longer set by default in docker-compose.yml. If your deployment targets private network URLs, set it explicitly.
    • Docker healthchecks now probe /api/ready (separate from /api/health); update any external monitors accordingly.
    • Config startup now rejects known dev secret keys — set real values (e.g. JWT_SECRET) before upgrading.
    • Log format and level can now be changed at runtime from the settings UI; the log_format field still requires a restart to apply (a WARN is logged noting this).

    Development / Internal

    Tests

    • New packages/server/tests/ suite with 29 passing tests: config validation; JWT round-trip and aud / alg=none rejection; SSRF scheme and private-range enforcement (sync + async); Discord bounded retry; a lifespan-level /api/health + /api/ready smoke check. services/test_dispatch.py renamed to manual_dispatch.py so pytest no longer auto-collects production code (920920b)

    CI / Build

    • CI now runs on push / PR with frontend svelte-check + build, and a non-push image build. Release workflow is gated on tests and publishes an immutable sha-<commit> image tag (920920b)
    • Install editable packages inside a venv (2bec253)
    • Cache pip downloads and collapse install into a single pip call (3b683ce)
    • Drop backend pytest from Gitea CI — editable install is too slow on the hosted runner (f904037)
    • Skip build.yml on release commits to avoid redundant runs (bbcdf1c)
    • Drop Trivy scan from release (output was discarded and it never failed) (19036a9)

    Performance

    • Split external Docker deps into a cacheable layer and swap pip for uv for faster image builds (592e1b6)
    • Install uv from PyPI instead of the ghcr.io distroless image to avoid slow GHCR pulls on CI (a6a854a)

    All Commits
    Hash Message Author
    8f0346e fix(csp): allow unsafe-inline scripts for SvelteKit hydration bootstrap alexei.dolgolyov
    a6a854a perf(docker): install uv from PyPI instead of ghcr.io (avoid slow GHCR pulls) alexei.dolgolyov
    19036a9 ci: drop trivy scan from release (never failed, output discarded) alexei.dolgolyov
    592e1b6 perf(docker): split external deps into a cacheable layer, swap pip for uv alexei.dolgolyov
    bbcdf1c ci: skip build.yml on release commits alexei.dolgolyov
    f904037 ci: drop backend pytest stage (too slow on hosted runner) alexei.dolgolyov
    3b683ce ci: cache pip downloads and collapse install into one pip call alexei.dolgolyov
    2bec253 ci: install editable packages inside a venv alexei.dolgolyov
    7cbb02b feat(db): pre-migration SQLite snapshots via VACUUM INTO alexei.dolgolyov
    920920b feat: production-readiness hardening across security, async, DB, ops alexei.dolgolyov
    f50d465 feat(logging): production-grade logging with context vars, secret masking, and runtime level control alexei.dolgolyov

    Changelog

    90def11 chore: release v0.4.0
    8f0346e fix(csp): allow unsafe-inline scripts for SvelteKit hydration bootstrap
    a6a854a perf(docker): install uv from PyPI instead of ghcr.io (avoid slow GHCR pulls)
    19036a9 ci: drop trivy scan from release (never failed, output discarded)
    592e1b6 perf(docker): split external deps into a cacheable layer, swap pip for uv
    bbcdf1c ci: skip build.yml on release commits
    f904037 ci: drop backend pytest stage (too slow on hosted runner)
    3b683ce ci: cache pip downloads and collapse install into one pip call
    2bec253 ci: install editable packages inside a venv
    e44d387 chore: release v0.4.0
    7cbb02b feat(db): pre-migration SQLite snapshots via VACUUM INTO
    920920b feat: production-readiness hardening across security, async, DB, ops
    f50d465 feat(logging): production-grade logging with context vars, secret masking, and runtime level control

    Downloads
  • v0.3.2 1f880daa0c

    Notify Bridge 0.3.2
    Release / release (push) Successful in 1m22s
    Stable

    alexei.dolgolyov released this 2026-04-23 13:38:28 +03:00 | 81 commits to master since this release

    v0.3.2 (2026-04-22)

    Scheduler now honors the app-level timezone. Before this, a cron expression
    like 0 9 * * * was firing at 09:00 in the server's host-local tz — not
    at 09:00 in the timezone the admin configured under Settings — because
    CronTrigger.from_crontab was constructed without a tz. Same fix extends
    to scheduler-provider template rendering so {{ current_date }} / {{ current_time }}
    match the configured tz, and scheduled firings now show up in the dashboard
    event feed with context.

    Bug Fixes

    • Cron triggers honor app timezone — all tracker and action cron triggers are now built with the configured app tz; CronTrigger freezes its tz at construction, so the PUT /settings endpoint rebuilds existing cron jobs when the timezone changes. Scheduled messages that were silently firing at host-local time will fire at the intended time after upgrade. (1024085)
    • Scheduler template context renders in the app tzcurrent_date, current_time, current_datetime, current_weekday in scheduler-provider templates are now formatted in the configured timezone instead of UTC/host-local. Custom templates that built date strings in the wrong tz now render correctly. (1024085)

    Features

    • New timezone template variable — scheduler-provider templates can reference {{ timezone }} to display the active IANA tz alongside a date/time. Added across the context builder, variable catalog, sample context, and runtime validator (per the project's 6-file sync rule for template vars). (1024085)
    • scheduled_message events surface in the dashboard feedEventLog entries for scheduled firings now carry schedule_type, cron_expression / interval_seconds, timezone, and fire_count; the dashboard renders them with a dedicated label, icon, and colour so operators can see at a glance when scheduled messages actually fired. (1024085)

    All Commits
    • 1024085 — fix(scheduler): honor app timezone for cron triggers and log scheduled events (alexei.dolgolyov)

    Changelog

    1f880da chore: release v0.3.2
    1024085 fix(scheduler): honor app timezone for cron triggers and log scheduled events

    Downloads
  • v0.3.1 5604c733d1

    Notify Bridge 0.3.1
    Release / release (push) Successful in 1m1s
    Stable

    alexei.dolgolyov released this 2026-04-22 19:27:45 +03:00 | 83 commits to master since this release

    v0.3.1 (2026-04-22)

    Follow-up perf pass on top of v0.3.0's polling overhaul — extends the same
    caching discipline to the bot-command read paths so repeat /random,
    /latest, /memory, etc. against the same album don't each refetch a
    multi-megabyte album body or pay for a full server-wide /api/shared-links
    listing.

    Performance

    • TTL-cache GET /api/albums/{id} responses — 60 s TTL, 32-entry FIFO cap, keyed by (server_digest, album_id). Module-scoped rather than instance-scoped because ImmichClient is constructed fresh per request in several places (api/providers.py, services/action_runner.py, command handlers), so an instance cache would never survive a second caller. Mirrors the existing _users_cache pattern. (3b7808a)
    • TTL-cache the bucketed shared-links map — 60 s TTL, keyed by server digest. /api/shared-links has no per-album filter, so every get_shared_links(album_id) call was already paying for the full server-wide list; now one fetch serves every album until the TTL elapses. (3b7808a)
    • Collapse concurrent cache misses to one fetch — async lock with an under-lock re-check around the album / shared-links populate step, so a burst of parallel commands hitting the same cold key issues one HTTP call instead of N. (3b7808a)
    • use_cache=False escape hatch on mutation / event-detection pathsImmichActionExecutor.execute (which diffs the current album state to decide what to add) and ImmichServiceProvider.poll's full-fetch path (where a stale entry would silently delay asset-removal events) explicitly bypass the cache. Non-cached fetches still populate it for subsequent readers. (3b7808a)

    All Commits
    • 3b7808a — perf(immich): TTL cache for album bodies and shared-link listings (alexei.dolgolyov)

    Changelog

    5604c73 chore: release v0.3.1
    3b7808a perf(immich): TTL cache for album bodies and shared-link listings

    Downloads