Files
alexei.dolgolyov 0eb899afb9 feat: harden notification stack and switch logging selectors to icon grid
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
2026-05-07 13:53:26 +03:00

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)

  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 — ALL provider-specific UI logic lives in provider descriptors (frontend/src/lib/providers/). NEVER add if (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_slots or capabilities.commands, not provider.type === 'immich'
    • Template variable helpers: ALL provider types must have entries in get_template_variables()
  9. 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 the children array under nav.targets, plus i18n keys nav.target{PascalName} in both locale files. Also add the counter entry targets_{type}: targets.filter(t => t.type === '{type}').length to the counts derived block in +layout.svelte.
  10. 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 the assets_added notification template. Command handlers must pass rich asset dicts (public_url, city, country, is_favorite, type) to templates — not just id and originalFileName.
  11. New provider descriptor checklist — when adding a new service provider, create a descriptor file in frontend/src/lib/providers/{name}.ts and register it in index.ts. The descriptor must define: type, defaultName, icon, hasUrl, configFields, buildConfig(), hasConfigChanged(), eventFields, collectionMeta (or null). Optional: extraTrackingFields, featureSections, webhookUrlPattern, webhookBased, onBeforeSave. Also add i18n keys: providers.type{PascalName} and gridDesc.provider{PascalName} in both en.json and ru.json.
  12. 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_ctx in preview_raw)
    • Runtime validator whitelist: packages/core/src/notify_bridge_core/templates/validator.py

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_nodes or query_graph instead of Grep
  • Understanding impact: get_impact_radius instead of manually tracing imports
  • Code review: detect_changes + get_review_context instead of reading entire files
  • Finding relationships: query_graph with 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

  1. The graph auto-updates on file changes (via hooks).
  2. Use detect_changes for code review.
  3. Use get_affected_flows to understand impact.
  4. Use query_graph pattern="tests_for" to check coverage.