Skip to content

feat(broadcasts): Always return minimum 3 broadcasts from org endpoint#110283

Closed
JonasBa wants to merge 1 commit intojb/refs/whatsnewfrom
jb/feat/broadcasts-minimum-three
Closed

feat(broadcasts): Always return minimum 3 broadcasts from org endpoint#110283
JonasBa wants to merge 1 commit intojb/refs/whatsnewfrom
jb/feat/broadcasts-minimum-three

Conversation

@JonasBa
Copy link
Member

@JonasBa JonasBa commented Mar 10, 2026

Stacked on #110269.

This PR modifies the broadcast API endpoint to always return the last 3 broadcasts regardless if they had been seen or not, which enables the frontend to control the visibility and not result in an experience where clicking a button inside a primary navigation leads to a blank dropdown with an empty state

Previously the org-scoped broadcasts endpoint returned only active,
non-expired broadcasts matching any secondary filters. If all broadcasts
had been seen, the frontend would show an empty panel.

After secondary filtering, if fewer than MIN_BROADCASTS (3) results
remain, backfill from the most recent active broadcasts not already in
the result set. This ensures the What's New panel always has content to
show, with seen/unseen styling providing the only distinction.

Inactive broadcasts are explicitly excluded from the backfill.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Mar 10, 2026
@JonasBa JonasBa marked this pull request as ready for review March 10, 2026 01:08
@JonasBa JonasBa requested a review from a team as a code owner March 10, 2026 01:08
Comment on lines +121 to +125
backfill = list(
Broadcast.objects.filter(is_active=True)
.exclude(id__in=existing_ids)
.order_by("-date_added")[: MIN_BROADCASTS - len(data)]
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Bug: The backfill query for broadcasts filters only on is_active=True, failing to exclude expired broadcasts based on date_expires, unlike the main query.
Severity: MEDIUM

Suggested Fix

Update the backfill Broadcast.objects.filter to include the same expiration check as the main queryset. Specifically, add the condition Q(date_expires__isnull=True) | Q(date_expires__gt=timezone.now()) to the filter to ensure expired broadcasts are not included in the backfill results.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/sentry/api/endpoints/broadcast_index.py#L121-L125

Potential issue: The main broadcast queryset correctly filters out expired broadcasts
using `Q(date_expires__isnull=True) | Q(date_expires__gt=timezone.now())`. However, the
backfill logic, intended to ensure a minimum number of broadcasts are shown, only
filters for `is_active=True`. This discrepancy means that if the primary query returns
fewer than `MIN_BROADCASTS`, the backfill can fetch and display broadcasts that have
already expired. This leads to outdated announcements being shown to users, which
contradicts the filtering logic used elsewhere in the application for the same purpose.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

backfill = list(
Broadcast.objects.filter(is_active=True)
.exclude(id__in=existing_ids)
.order_by("-date_added")[: MIN_BROADCASTS - len(data)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Backfill query omits date_expires filter allowing expired broadcasts

Medium Severity

The backfill query only filters by is_active=True, but the main queryset (lines 80–82) also filters out expired broadcasts with Q(date_expires__isnull=True) | Q(date_expires__gt=timezone.now()). Since date_expires defaults to 7 days after creation, many older broadcasts will have a past expiry date. The backfill can surface these expired broadcasts to users, undermining the expiration logic.

Additional Locations (1)

Fix in Cursor Fix in Web

@JonasBa JonasBa closed this Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant