Commit Graph

10 Commits

Author SHA1 Message Date
alexei.dolgolyov f9c41faf16 fix: local fonts via @fontsource, favicon, autocomplete attrs
- Replace Google Fonts with @fontsource/dm-sans and @fontsource/jetbrains-mono
- Add SVG favicon
- Add autocomplete attributes to login/setup form inputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:13:21 +03:00
alexei.dolgolyov 786fe5ec3d feat(notify-bridge): phase 9 - HAOS integration planning
Architecture documentation for HAOS integration with Notify Bridge:
- Polling-based event stream API (recommended for Phase 1)
- WebSocket option for future real-time enhancement
- Feature obsolescence analysis: what moves to Bridge vs stays in HAOS
- New HAOS integration flow: Bridge URL -> JWT auth -> poll events
- Entity mapping: sensors, binary sensors, cameras, buttons
- API contract: /api/events/stream, /api/trackers/{id}/state
- 4-phase migration path from direct Immich to Bridge client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:55:56 +03:00
alexei.dolgolyov 08814e9ae2 feat(notify-bridge): phase 8 - integration and wiring
Wire all components into a working application:
- Scheduler service: APScheduler loads enabled trackers, polls at intervals
- Watcher service: orchestrates poll -> detect -> notify flow
  - Eagerly loads DB data, then creates aiohttp session for provider
  - Saves tracker state after each poll
  - Logs events to EventLog table
  - Dispatches notifications to targets with template rendering
- Manual trigger endpoint: POST /api/trackers/{id}/trigger
- Scheduler starts on app lifespan startup
- Full end-to-end flow verified: server starts cleanly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:55:15 +03:00
alexei.dolgolyov 9dfd1b79cd feat(notify-bridge): phase 7 - frontend restructuring
Notify Bridge frontend with SvelteKit 2 + Svelte 5 + Tailwind CSS v4:
- Auth: login page, setup page, auth state management with $state runes
- Theme: dark/light toggle with localStorage persistence
- i18n: EN/RU translations with reactive $state-based t() function
- Routes: dashboard, providers, trackers, targets, tracking-configs,
  template-configs, telegram-bots, users (stubs for configs pages)
- Providers page: list with card grid, "Add Provider" button
- API client: JWT auth, auto-redirect on 401, typed request helpers
- Branding: "Notify Bridge" throughout, Observatory theme colors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:53:37 +03:00
alexei.dolgolyov 7f99c895a4 feat(notify-bridge): phase 6 - database models and server API
New database schema with ServiceProvider abstraction:
- ServiceProvider (replaces ImmichServer): type + JSON config
- Tracker (replaces AlbumTracker): owns tracking_config_id
- TrackingConfig: provider_type scoped, owned by Tracker
- TemplateConfig: provider_type scoped, owned by Target
- NotificationTarget: owns template_config_id (not tracking_config_id)
- TrackerState, EventLog, User, TelegramBot, TelegramChat

Full FastAPI server:
- /api/providers: CRUD + test connection + list collections
- /api/trackers: CRUD
- /api/tracking-configs: CRUD with provider_type filter
- /api/template-configs: CRUD with provider_type filter, system defaults
- /api/targets: CRUD
- /api/template-vars: variable docs filtered by provider type
- /api/auth: setup, login, refresh, me, password change
- /api/health: health check
- Default template seeding on first startup (EN/RU for Immich)
- pydantic-settings with NOTIFY_BRIDGE_ env prefix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:39:23 +03:00
alexei.dolgolyov 16a41efec1 feat(notify-bridge): phase 5 - notification system
Extract and generalize notification dispatch:
- TelegramClient: full Bot API client with photo/video/document/media group support
- TelegramFileCache: TTL and thumbhash-based file_id caching
- WebhookClient: simple JSON POST client
- NotificationQueue: persistent deferred notification queue for quiet hours
- NotificationDispatcher: routes ServiceEvent to targets, renders templates
- StorageBackend protocol + JsonFileBackend for persistence
- TargetConfig dataclass for target configuration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:28:10 +03:00
alexei.dolgolyov f36f070478 feat(notify-bridge): phase 4 - template system
Implement hybrid template system:
- Jinja2 SandboxedEnvironment renderer with error fallback
- Context builder: transforms ServiceEvent into flat template variables
- Template validator: checks variable references against provider type
- Default templates in EN/RU for all 8 event slots (Immich provider)
- Template loader reads .jinja2 files, returns slot->content dict
- Slots: assets_added/removed, collection_renamed/deleted, sharing_changed,
  periodic_summary, scheduled_assets, memory_mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:49:03 +03:00
alexei.dolgolyov cc02558fdf feat(notify-bridge): phase 3 - Immich service provider
Implement ImmichServiceProvider as first concrete ServiceProvider:
- ImmichClient: async API client (ping, albums, shared links, search, thumbnails)
- ImmichAssetInfo/ImmichAlbumData: Immich-specific models with from_api_response()
- Change detector: produces generic ServiceEvent from album diffs
- Asset utils: filter, sort, URL building for Immich assets
- 12 Immich-specific template variables registered in global VariableRegistry
- Provider config schema (url, api_key, external_domain)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:37:17 +03:00
alexei.dolgolyov 3ed0d8ce88 feat(notify-bridge): phase 2 - core abstractions
Define the generic provider/event/variable system:
- ServiceProvider ABC with connect, disconnect, poll, list_collections
- ServiceProviderType enum (IMMICH first)
- EventType enum (assets_added/removed, collection_renamed/deleted, sharing_changed)
- MediaAsset, MediaCollection, CollectionState dataclasses
- TemplateVariableDefinition and VariableRegistry with 11 base variables
- All models use extra: dict for provider-specific data passthrough

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:33:11 +03:00
alexei.dolgolyov b724447f4d feat(notify-bridge): phase 1 - project scaffolding
Set up the Notify Bridge project structure:
- packages/core (notify_bridge_core) with provider, model, notification, template packages
- packages/server (notify_bridge_server) with FastAPI skeleton and health endpoint
- frontend with SvelteKit 2, Svelte 5, Tailwind CSS v4, static adapter
- Root configs: .gitignore, README.md, CLAUDE.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:30:06 +03:00