68ac13b452
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
35 lines
3.9 KiB
Markdown
35 lines
3.9 KiB
Markdown
# 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](.claude/docs/dev-servers.md) | **MUST restart backend after code changes**; frontend restart on request |
|
|
| Frontend architecture | [frontend-architecture.md](.claude/docs/frontend-architecture.md) | Svelte 5 runes, overlays, entity cache system, i18n, auth flow |
|
|
| Backend architecture | [backend-architecture.md](.claude/docs/backend-architecture.md) | SQLAlchemy async constraints, Jinja2 sandbox, route ordering |
|
|
| Entity relationships | [entity-relationships.md](.claude/docs/entity-relationships.md) | Full entity graph and DB conventions |
|
|
| Template system | [template-system.md](.claude/docs/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](.claude/docs/dev-servers.md) for the one-liner.
|
|
2. **Overlays** MUST use `position: fixed` with inline styles and `z-index: 9999` — see [frontend-architecture.md](.claude/docs/frontend-architecture.md).
|
|
3. **Template variables** must be updated in 6 files simultaneously — see [template-system.md](.claude/docs/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](.claude/docs/frontend-architecture.md).
|
|
5. **Selector placeholders** — use plain text without decorative dashes. `Select provider...` not `— Select provider —` — see [frontend-architecture.md](.claude/docs/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()`
|