Files
notify-bridge/CLAUDE.md
T
alexei.dolgolyov 68ac13b452 feat: NUT (Network UPS Tools) service provider + provider-agnostic UI
Add full NUT support as a polling-based service provider:
- Async TCP client for upsd protocol (port 3493, configurable)
- 8 event types: online, on_battery, low_battery, battery_restored,
  comms_lost, comms_restored, replace_battery, overload
- 3 bot commands: /status, /devices, /battery
- 38 Jinja2 templates (EN+RU notification + command templates)
- Database: tracking config fields, migration, seeds
- Frontend: provider form with host/port/credentials, grid items, i18n

Provider-agnostic UI improvements:
- Remove hardcoded 'immich' defaults from all config forms
- Dynamic collection labels per provider type (Albums/Repos/Boards/UPS Devices)
- Capability-driven test types instead of provider type checks
- Template variable helpers for all providers (was Immich-only)
- Guard Immich-only shared link check to Immich providers
- Auto-clear stale global provider filter from localStorage
- EntitySelect search placeholder shows current selection
- Fix noneLabel in linked target config selectors

New CLAUDE.md rule #8: no provider-specific hardcoding
2026-03-23 23:23:58 +03:00

3.9 KiB

Project Guidelines

Detailed context is split into focused documents under .claude/docs/. Read the relevant file when working in that area.

Area File Key rules
Dev servers & credentials dev-servers.md MUST restart backend after code changes; frontend restart on request
Frontend architecture frontend-architecture.md Svelte 5 runes, overlays, entity cache system, i18n, auth flow
Backend architecture backend-architecture.md SQLAlchemy async constraints, Jinja2 sandbox, route ordering
Entity relationships entity-relationships.md Full entity graph and DB conventions
Template system template-system.md 6-file sync rule for template variables

Critical Rules (always apply)

  1. Restart backend after ANY change to packages/server/ or packages/core/ — see dev-servers.md for the one-liner.
  2. Overlays MUST use position: fixed with inline styles and z-index: 9999 — see frontend-architecture.md.
  3. Template variables must be updated in 6 files simultaneously — see template-system.md.
  4. Entity cache — shared entities use $state-based caches in frontend/src/lib/stores/caches.svelte.ts. Always use cache for cross-page data; invalidate after mutations — see frontend-architecture.md.
  5. Selector placeholders — use plain text without decorative dashes. Select provider... not — Select provider — — see frontend-architecture.md.
  6. Telegram API — ALL Telegram Bot API calls (sendMessage, sendPhoto, sendMediaGroup, etc.) MUST go through TelegramClient in packages/core/src/notify_bridge_core/notifications/telegram/client.py. NEVER duplicate sending logic in command handlers, API routes, or services. If TelegramClient lacks a method you need, add it there.
  7. Service provider defaults — when implementing a new service provider, ALWAYS create default notification and command templates and configs. This requires changes across all of these locations:
    • Jinja2 notification templates for each locale in packages/core/src/notify_bridge_core/templates/defaults/{en,ru}/
    • Jinja2 command templates for each locale in packages/core/src/notify_bridge_core/templates/command_defaults/{en,ru}/{provider}/
    • Notification slot mapping in packages/core/src/notify_bridge_core/templates/defaults/loader.py (PROVIDER_SLOT_FILE_MAP)
    • Command slot mapping in packages/core/src/notify_bridge_core/templates/command_defaults/loader.py (PROVIDER_COMMAND_SLOTS)
    • Provider capabilities in packages/core/src/notify_bridge_core/providers/capabilities.py
    • Seed functions in packages/server/src/notify_bridge_server/database/seeds.py (notification templates, command templates, tracking configs, command configs)
    • Template variable definitions in packages/server/src/notify_bridge_server/api/template_configs.py (get_template_variables())
  8. No provider-specific hardcoding — UI labels, icons, form defaults, and feature checks MUST be provider-agnostic. NEVER hardcode a specific provider type (e.g. 'immich') where multiple providers could appear:
    • Form defaults: use provider_type: '' (empty), not 'immich'
    • Collection labels: use the collectionMeta lookup in TrackerForm.svelte, not hardcoded "Albums"
    • Feature gating: check capabilities.notification_slots or capabilities.commands, not provider.type === 'immich'
    • Provider-specific API calls (e.g. /albums/.../shared-links): guard with a provider type check
    • Template variable helpers: ALL provider types must have entries in get_template_variables()