Skip to content

fix(alerts): send the destination-kind descriptors to the account page#314

Merged
icebergai-review-bot[bot] merged 2 commits into
mainfrom
fix/destination-kinds-island
Jul 20, 2026
Merged

fix(alerts): send the destination-kind descriptors to the account page#314
icebergai-review-bot[bot] merged 2 commits into
mainfrom
fix/destination-kinds-island

Conversation

@richardmhope

Copy link
Copy Markdown
Collaborator

Closes #313

The bug

The Type dropdown on /accountNew destination renders zero options, so
no alert destination can be created from the UI. Shipped with #311; present on main.

Cause

routes/ui.py passes destination_kinds into the account-page context, and
app/senders/base.py:kind_descriptors documents itself as feeding "both the
GET /api/alerts/destination-kinds endpoint and the account-page JSON island"
.

The account-data island only serialised destinations/rules/extensions/alert_log.
So data.destination_kinds was undefined, destinationKinds fell back to [], and
x-for="k in destinationKinds" produced no <option>s.

Blast radius

Wider than the dropdown — selectedKind resolves to null, so kindConfigFields
returns [] (no kind-specific config fields render), targetLabel degrades to a generic
"Target", and the availability warning is suppressed. Slack / Teams / email / Jira /
ServiceNow destinations were unreachable from the UI. The JSON API is unaffected.

Fix

One missing key in the island literal.

Why the existing tests passed

The page reads the island; it never calls the API endpoint. The endpoint's own tests
therefore prove nothing about it. The new tests assert on the rendered island and that
it matches kind_descriptors() exactly — the contract that drifted.

Verification

  • 4 new tests in tests/test_account_destination_kinds.py; confirmed failing against
    the pre-fix template and passing after.
  • Full suite: 946 passed. ruff check / ruff format --check clean.
  • Driven in a real browser against the dev app: all six kinds populate
    (Webhook, Slack, Microsoft Teams, Email (SMTP), Jira, ServiceNow) and selecting
    ServiceNow renders its instance-base-URL field. Zero console errors.

Docs

  • CHANGELOG.md under Fixed.
  • .claude/rules/frontend.md: the island is a hand-maintained contract — adding a key to
    the route context is only half the change, and the component's || [] fallback hides the
    omission with no error and a green suite.

🤖 Generated with Claude Code

#311)

The Type dropdown on /account rendered zero options, so no alert destination
could be created from the UI.

routes/ui.py passes `destination_kinds` into the account.html context and
senders/base.py:kind_descriptors documents itself as feeding "both the
GET /api/alerts/destination-kinds endpoint and the account-page JSON island" —
but the island only serialised destinations/rules/extensions/alert_log. So
`data.destination_kinds` was undefined in accountPrefs, `destinationKinds` fell
back to [], and `x-for="k in destinationKinds"` produced no <option>s.

The blast radius is wider than the dropdown: selectedKind resolves to null, so
kindConfigFields returns [] and the kind-specific config fields never render,
targetLabel degrades to "Target", and the availability warning is suppressed.
Slack/Teams/email/Jira/ServiceNow destinations were unreachable from the UI.

Fix is the one missing key in the island. The page never calls the API endpoint,
so the endpoint's own tests could not have caught this — the new tests assert on
the rendered island and that it matches kind_descriptors() exactly, which is the
contract that drifted.

Verified in a browser against the dev app: all six kinds populate and selecting
ServiceNow renders its instance-base-URL field. Zero console errors.
- CHANGELOG: the #311 Type-dropdown regression under Fixed, including why an
  endpoint test could not have caught it.
- .claude/rules/frontend.md: the island is a hand-maintained contract — adding a
  key to the route context is only half the change. A context key the template
  never serialises reaches nothing, and the component's `|| []` fallback hides it
  with no error and a green suite. Assert on the rendered island, not the API.

@icebergai-review-bot icebergai-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IcebergAutoReview

Verdict: approve

The one-key JSON-island fix correctly restores destination descriptors to the account-page component. It uses the existing sender registry as the source of truth and includes focused rendered-response regression coverage. No blocking correctness or security issues found.

Findings

  • No blocking findings.

Validation

  • Inspected the complete main...HEAD diff and verified HEAD is directly based on local main.
  • Traced destination descriptors through sender registry → UI route context → Jinja JSON island → Alpine component.
  • Attempted focused pytest file; unavailable locally because the read-only checkout prevented uv from creating .venv, while system pytest lacked pytest_asyncio. Current-head CI is green.

Residual risks / optional notes

  • Minor documentation drift: the account.js header comment still lists only the four original island fields, and new documentation cites #311 rather than the fixing issue #313. Neither affects runtime behavior.

Automated review by Codex 178b3d3f765a using IcebergAutoReview.

@icebergai-review-bot
icebergai-review-bot Bot merged commit 7f5f595 into main Jul 20, 2026
11 checks passed
@icebergai-review-bot
icebergai-review-bot Bot deleted the fix/destination-kinds-island branch July 20, 2026 11:34
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.

Alert destination Type dropdown is empty — no destination can be created from the UI

1 participant