0eb899afb9
Notifications: - Add shared http_base, redact, and SSRF hardening modules - Refactor dispatcher, queue, receiver and per-provider clients (telegram, discord, email, matrix, ntfy, slack, webhook) to use the shared base, with bounded queue and redacted error logs - Tests for ssrf, redact, http_base, queue bounds, dispatcher aggregation, telegram media partition, email and matrix clients Frontend: - Settings: log level / log format selectors now use IconGridSelect with per-option icons and i18n descriptions - Minor providers page and entity-cache store updates Tooling: - Document code-review-graph MCP usage in CLAUDE.md - Ignore .code-review-graph/, register .mcp.json
8.1 KiB
8.1 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)
- Restart backend after ANY change to
packages/server/orpackages/core/— see dev-servers.md for the one-liner. - Overlays MUST use
position: fixedwith inline styles andz-index: 9999— see frontend-architecture.md. - Template variables must be updated in 6 files simultaneously — see template-system.md.
- Entity cache — shared entities use
$state-based caches infrontend/src/lib/stores/caches.svelte.ts. Always use cache for cross-page data; invalidate after mutations — see frontend-architecture.md. - Selector placeholders — use plain text without decorative dashes.
Select provider...not— Select provider —— see frontend-architecture.md. - Telegram API — ALL Telegram Bot API calls (sendMessage, sendPhoto, sendMediaGroup, etc.) MUST go through
TelegramClientinpackages/core/src/notify_bridge_core/notifications/telegram/client.py. NEVER duplicate sending logic in command handlers, API routes, or services. IfTelegramClientlacks a method you need, add it there. - 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())
- Jinja2 notification templates for each locale in
- No provider-specific hardcoding — ALL provider-specific UI logic lives in provider descriptors (
frontend/src/lib/providers/). NEVER addif (type === 'xyz')in components.- Form fields, validation, config building → defined in the descriptor's
configFields/buildConfig/hasConfigChanged - Event tracking checkboxes →
eventFields; extra controls →extraTrackingFields; feature sections (periodic/scheduled/memory) →featureSections - Collection labels/icons →
collectionMeta; webhook URL display →webhookUrlPattern - Pre-save hooks (e.g. shared-link validation) →
onBeforeSave - Components use
getDescriptor(type)and render dynamically from the descriptor - Feature gating: check
capabilities.notification_slotsorcapabilities.commands, notprovider.type === 'immich' - Template variable helpers: ALL provider types must have entries in
get_template_variables()
- Form fields, validation, config building → defined in the descriptor's
- Nav tree & entity types — when adding a new entity type (target type, bot type, etc.), update the sidebar nav in
frontend/src/routes/+layout.svelte. Target types need:{ href: '/targets?type={type}', key: 'nav.target{PascalName}', icon: '...', countKey: 'targets_{type}' }in thechildrenarray undernav.targets, plus i18n keysnav.target{PascalName}in both locale files. Also add the counter entrytargets_{type}: targets.filter(t => t.type === '{type}').lengthto thecountsderived block in+layout.svelte. - Template consistency (IMPORTANT) — notification templates and command templates for the same provider MUST use the same formatting patterns. If notification templates wrap URLs in
<a href>, show type icons, location, and favorite status for assets, command templates must do the same. The reference pattern is theassets_addednotification template. Command handlers must pass rich asset dicts (public_url,city,country,is_favorite,type) to templates — not justidandoriginalFileName. - New provider descriptor checklist — when adding a new service provider, create a descriptor file in
frontend/src/lib/providers/{name}.tsand register it inindex.ts. The descriptor must define:type,defaultName,icon,hasUrl,configFields,buildConfig(),hasConfigChanged(),eventFields,collectionMeta(ornull). Optional:extraTrackingFields,featureSections,webhookUrlPattern,webhookBased,onBeforeSave. Also add i18n keys:providers.type{PascalName}andgridDesc.provider{PascalName}in bothen.jsonandru.json. - Template context variables (IMPORTANT) — when adding new variables to templates, update ALL of these in sync:
- Runtime context builder:
packages/core/src/notify_bridge_core/templates/context.py - Variable docs:
packages/server/src/notify_bridge_server/api/template_configs.py(get_template_variables()) - Notification preview sample:
packages/server/src/notify_bridge_server/services/sample_context.py(_SAMPLE_CONTEXT) - Command preview sample:
packages/server/src/notify_bridge_server/api/command_template_configs.py(sample_ctxinpreview_raw) - Runtime validator whitelist:
packages/core/src/notify_bridge_core/templates/validator.py
- Runtime context builder:
MCP Tools: code-review-graph
IMPORTANT: This project has a knowledge graph. ALWAYS use the code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore the codebase. The graph is faster, cheaper (fewer tokens), and gives you structural context (callers, dependents, test coverage) that file scanning cannot.
When to use graph tools FIRST
- Exploring code:
semantic_search_nodesorquery_graphinstead of Grep - Understanding impact:
get_impact_radiusinstead of manually tracing imports - Code review:
detect_changes+get_review_contextinstead of reading entire files - Finding relationships:
query_graphwith callers_of/callees_of/imports_of/tests_for - Architecture questions:
get_architecture_overview+list_communities
Fall back to Grep/Glob/Read only when the graph doesn't cover what you need.
Key Tools
| Tool | Use when |
|---|---|
detect_changes |
Reviewing code changes — gives risk-scored analysis |
get_review_context |
Need source snippets for review — token-efficient |
get_impact_radius |
Understanding blast radius of a change |
get_affected_flows |
Finding which execution paths are impacted |
query_graph |
Tracing callers, callees, imports, tests, dependencies |
semantic_search_nodes |
Finding functions/classes by name or keyword |
get_architecture_overview |
Understanding high-level codebase structure |
refactor_tool |
Planning renames, finding dead code |
Workflow
- The graph auto-updates on file changes (via hooks).
- Use
detect_changesfor code review. - Use
get_affected_flowsto understand impact. - Use
query_graphpattern="tests_for" to check coverage.