Skip to content

refactor(alerts): drop fetch from AlertRuntime, use the runtime HttpClient - #1261

Merged
Makisuo merged 1 commit into
mainfrom
claude/nervous-liskov-efb755
Oct 5, 2026
Merged

Makisuo merged 1 commit into
mainfrom
claude/nervous-liskov-efb755

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

What

Follow-up to #1257. Alert delivery already runs on the HttpClient from the app runtime, but AlertRuntime still exposed a raw fetch. This removes it.

  • AlertRuntimeApi loses fetch; dispatchDelivery / TransportRuntime lose fetchFn, and runTransport no longer overrides FetchHttpClient.Fetch per send. NotificationDispatcher was also passing globalThis.fetch and is updated.
  • Telegram chat discovery (fetchTelegramChats), the Telegram credential check (verifyTelegramCredentials) and the PagerDuty routing-key check (verifyPagerDutyRoutingKey) now require HttpClient.HttpClient. AlertDestinationsService provides the client it acquires in its constructor via Effect.provideService.
  • Tests that injected a fake fetch through AlertRuntime overrides or the dispatchDelivery argument now provide it as FetchHttpClient.Fetch. AlertsService.test.ts keeps a fetch key on makeLayer's overrides so its call sites stay unchanged; it is wired to FetchHttpClient.Fetch.

Reviewer notes

  • The Telegram Bot API calls set HttpClient.TracerDisabledWhen to constTrue: the bot token is in the URL path and the client span records url.full. Same reasoning as delivery in runTransport.
  • PagerDuty key verification is not guarded and keeps the client span (fixed URL, the key is in the body).
  • The "fetch detached from the runtime object" regression test can no longer regress the old way; it is kept as a check that the fetch client calls fetch as a bare function.

Verification

  • tsc --noEmit clean in packages/backend and apps/api; effect lint clean on the changed files.
  • vitest run on AlertsService, AlertRulesService, AlertDeliveryDispatch*, delivery/** (171 tests) and apps/api alerts.http + alchemy-provider.integration (18 tests): all pass.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Devin Review

Summary by CodeRabbit

  • Refactor
    • Alert delivery and destination verification now use a shared HTTP client, while preserving existing timeouts and response handling.
    • Telegram requests continue to protect bot tokens in request URLs from client tracing.
  • Tests
    • Updated alert delivery and verification tests to provide mocked HTTP responses through the shared client.

…lient

Alert delivery already runs on the HttpClient from the app runtime, but
AlertRuntime still carried a raw `fetch` that dispatchDelivery used only to
override FetchHttpClient.Fetch per send, and that the save-time checks
(Telegram chat discovery, Telegram credential check, PagerDuty routing key
check) called directly.

- Remove `fetch` from AlertRuntimeApi and `fetchFn` from dispatchDelivery /
  TransportRuntime (NotificationDispatcher passed globalThis.fetch too).
- fetchTelegramChats, verifyTelegramCredentials and verifyPagerDutyRoutingKey
  require HttpClient; AlertDestinationsService provides the client it acquires
  in its constructor. Telegram calls disable the client span because the bot
  token is in the URL path.
- Tests provide their fake wire as FetchHttpClient.Fetch.
@maple-review-bot

maple-review-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 4/5 · likely safe to merge
Every production hunk is a semantics-preserving swap of the raw fetch for the ambient client, and all call sites and fake-fetch wirings were updated together.
quality 100/100 · no findings · tests covered · risk low · 2/3 new units observable

Removes the raw fetch from AlertRuntime and routes alert delivery, Telegram verification and the PagerDuty key check through the runtime HttpClient (fake wire injected as FetchHttpClient.Fetch). The refactor is equivalent in behavior; nothing here needs changing before merge.

  • dispatchDelivery and TransportRuntime drop fetchFn; delivery uses the ambient HttpClient
  • telegramGet replaces raw fetch and suppresses the client span for the token-bearing URL
  • verifyPagerDutyRoutingKey posts via HttpClientRequest/HttpClient.execute
  • AlertRuntimeApi loses fetch; tests inject FetchHttpClient.Fetch instead
What was checked
  • telegramGet keeps old semantics: ok from status >= 200 && < 300 (telegram.ts:157) equals fetch's response.ok, and the timeout still wraps each discovery call
  • HttpClient.TracerDisabledWhen provided around the call is the repo's established pattern (apps/cli/src/commands/server.ts:499, lib/safe-fetch/src/index.ts:235, runTransport.ts:139), so the bot…
  • Body reads stay in the request continuation (telegram.ts:155, pagerduty.ts:108), matching ElectricClient.ts:271 and the CLI, so no scope-closed read
Observability coverage: 2 of 3 changes observable
Change Kind Observable Evidence
Telegram Bot API GET (getMe/getChat/getUpdates) via HttpClient outbound call no Client span deliberately suppressed via HttpClient.TracerDisabledWhen at telegram.ts:163 — bot token is in the URL path
PagerDuty routing-key verification POST via HttpClient outbound call yes pagerduty.ts:91-101 now emits the client span for the fixed vendor host (routing key is in the body)
Alert delivery provider sends via HttpClient outbound call yes runTransport.ts:133 keeps the AlertDelivery.http client span with peer.service; only the per-send FetchHttpClient.Fetch override was removed

1b9274f · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce3820ac-67f6-4fc3-9c48-70dcc13744a0
📥 Commits

Reviewing files that changed from the base of the PR and between 1b177f5 and 1b9274f.

📒 Files selected for processing (17)
  • apps/api/src/routes/v2/alchemy-provider.integration.test.ts
  • apps/api/src/routes/v2/alerts.http.test.ts
  • packages/backend/src/services/alerts/AlertDeliveryDispatch.providers.test.ts
  • packages/backend/src/services/alerts/AlertDeliveryDispatch.test.ts
  • packages/backend/src/services/alerts/AlertDestinationDelivery.ts
  • packages/backend/src/services/alerts/AlertDestinationsService.ts
  • packages/backend/src/services/alerts/AlertRulesService.test.ts
  • packages/backend/src/services/alerts/AlertRuntime.ts
  • packages/backend/src/services/alerts/AlertsService.test.ts
  • packages/backend/src/services/alerts/NotificationDispatcher.ts
  • packages/backend/src/services/alerts/delivery/delivery-spans.test.ts
  • packages/backend/src/services/alerts/delivery/dispatch.ts
  • packages/backend/src/services/alerts/delivery/runTransport.ts
  • packages/backend/src/services/alerts/delivery/transports/chat.test.ts
  • packages/backend/src/services/alerts/delivery/transports/pagerduty.ts
  • packages/backend/src/services/alerts/delivery/transports/telegram.test.ts
  • packages/backend/src/services/alerts/delivery/transports/telegram.ts
💤 Files with no reviewable changes (6)
  • packages/backend/src/services/alerts/NotificationDispatcher.ts
  • apps/api/src/routes/v2/alerts.http.test.ts
  • packages/backend/src/services/alerts/AlertDestinationDelivery.ts
  • packages/backend/src/services/alerts/AlertRulesService.test.ts
  • apps/api/src/routes/v2/alchemy-provider.integration.test.ts
  • packages/backend/src/services/alerts/AlertRuntime.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Alert delivery and destination verification now use the Effect HttpClient service. The runtime and transport function signatures no longer pass fetch; tests provide mocked fetch implementations through FetchHttpClient.

Changes

Alerts HTTP client migration

Layer / File(s) Summary
PagerDuty and Telegram HTTP clients
packages/backend/src/services/alerts/delivery/transports/pagerduty.ts, packages/backend/src/services/alerts/delivery/transports/telegram.ts, packages/backend/src/services/alerts/delivery/transports/telegram.test.ts
PagerDuty verification and Telegram requests use Effect HttpClient. Telegram response handling and existing verification and chat-discovery classifications remain in place. Tests provide mocked fetch through FetchHttpClient.
Alert delivery and runtime wiring
packages/backend/src/services/alerts/AlertRuntime.ts, packages/backend/src/services/alerts/AlertDestinationDelivery.ts, packages/backend/src/services/alerts/AlertDestinationsService.ts, packages/backend/src/services/alerts/NotificationDispatcher.ts, packages/backend/src/services/alerts/delivery/{dispatch.ts,runTransport.ts}, packages/backend/src/services/alerts/*test.ts, packages/backend/src/services/alerts/delivery/*test.ts, packages/backend/src/services/alerts/delivery/transports/chat.test.ts, apps/api/src/routes/v2/*test.ts
AlertRuntime and the delivery dispatch path no longer pass fetch. Destination operations use the HttpClient service. Test helpers and fixtures provide fetch through FetchHttpClient.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Suggested reviewers: jeremyfunk

Merge Risk: ⚪ Minimal · up to 1b927

This refactor moves alert HTTP calls onto the shared HttpClient service without changing destinations or result handling. No concrete merge-blocking risk remains.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 1b927

The reviewed paths preserve administrator checks, tenant-scoped storage, outbound URL protection, and token-safe tracing. No introduced security issue was established. The shared dependency change has limited residual uncertainty around consumers and runtime configurations outside the reviewed paths.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The dependency change spans shared alert delivery and administrator-driven destination checks. Telegram discovery authority remains determined by the supplied bot token and its accessible chats, while destination persistence remains organization-scoped. The reviewed changes do not establish increased authority or tenant reach.

Trust Boundaries and Controls

  • observed — The Telegram discovery route obtains roles from CurrentTenant, and the service requires root or org-admin authority before validating the token and issuing a request. The token pattern excludes URL-control characters, the Telegram origin is fixed, and delivery still applies the safe-fetch guard to destinations marked guarded. Token syntax validation is separate from authorization.

Resilience and Maintainability Implications

  • observed — Telegram discovery retains its no-offset request and local deduplication without introducing a persisted cursor. PagerDuty verification retains a resolve request with a fresh maple-keycheck UUID rather than an alert's deduplication key. These request identities and the existing timeout verdicts are unchanged, limiting new transition or recovery risk from client substitution.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: removing fetch from AlertRuntime and using the runtime HttpClient for alerts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@Makisuo
Makisuo merged commit 4befde6 into main Oct 5, 2026
38 checks passed
@Makisuo
Makisuo deleted the claude/nervous-liskov-efb755 branch October 5, 2026 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant