Skip to content

Conversation

@edwardgou-sentry
Copy link
Contributor

@edwardgou-sentry edwardgou-sentry commented Oct 22, 2025

Lazily creates prebuilt dashboards on fetch if they do not already exist in the database. Stored prebuilt dashboards are mostly empty except for a prebuilt_id that will be used in the frontend to determine the type of content to display in the ui.
Model changes:

  • Adds prebuilt_id as a new column in the dashboards model + a constraint
  • Updates created_by_id to be nullable, since prebuilt dashboards are not created by a user

https://linear.app/getsentry/document/how-will-we-store-static-dashboards-0d85ebe8c8ae

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Oct 22, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 22, 2025

This PR has a migration; here is the generated SQL for src/sentry/migrations/0998_add_prebuilt_id_to_dashboards.py

for 0998_add_prebuilt_id_to_dashboards in sentry

--
-- Add field prebuilt_id to dashboard
--
ALTER TABLE "sentry_dashboard" ADD COLUMN "prebuilt_id" integer DEFAULT NULL NULL CHECK ("prebuilt_id" >= 0);
--
-- Alter field created_by_id on dashboard
--
ALTER TABLE "sentry_dashboard" ALTER COLUMN "created_by_id" DROP NOT NULL;
--
-- Create constraint sentry_dashboard_organization_prebuilt_id_uniq on model dashboard
--
CREATE UNIQUE INDEX CONCURRENTLY "sentry_dashboard_organization_prebuilt_id_uniq" ON "sentry_dashboard" ("organization_id", "prebuilt_id") WHERE "prebuilt_id" IS NOT NULL;
--
-- Create constraint sentry_dashboard_prebuilt_null_created_by on model dashboard
--
ALTER TABLE "sentry_dashboard" ADD CONSTRAINT "sentry_dashboard_prebuilt_null_created_by" CHECK (("prebuilt_id" IS NULL OR "created_by_id" IS NULL)) NOT VALID;
ALTER TABLE "sentry_dashboard" VALIDATE CONSTRAINT "sentry_dashboard_prebuilt_null_created_by";

@codecov
Copy link

codecov bot commented Oct 22, 2025

Codecov Report

❌ Patch coverage is 89.18919% with 4 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ry/dashboards/endpoints/organization_dashboards.py 86.20% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #101968      +/-   ##
===========================================
+ Coverage   73.25%    80.96%   +7.71%     
===========================================
  Files        8726      8729       +3     
  Lines      388171    388444     +273     
  Branches    24628     24627       -1     
===========================================
+ Hits       284347    314519   +30172     
+ Misses     103464     73565   -29899     
  Partials      360       360              

@edwardgou-sentry edwardgou-sentry marked this pull request as ready for review October 22, 2025 22:13
@edwardgou-sentry edwardgou-sentry requested review from a team as code owners October 22, 2025 22:13
@edwardgou-sentry edwardgou-sentry requested a review from a team October 22, 2025 22:13
@edwardgou-sentry
Copy link
Contributor Author

Theres an awkward thing where we already have an existing concept of prebuilt dashboards ie the default-overview dashboard, but we should plan for it to be deprecated and deleted.

Comment on lines +295 to +298
for id in dashboards.values_list("created_by_id", flat=True).filter(
created_by_id__isnull=False
)
if id is not None
Copy link
Member

Choose a reason for hiding this comment

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

If you're excluding none in the conditions, I don't think this filter condition will be hit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I had to add this here because mypy would still interpret id as int | None despite the filter condition.
I think this should be fine? Alternatively should we just add a type ignore? Let me know what you think!

Copy link
Member

Choose a reason for hiding this comment

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

ah ok. Sacrifices must be made to the mypy gods 🔥

assert final_count == initial_count
assert final_count == len(PREBUILT_DASHBOARDS)

def test_endpoint_deletes_old_prebuilt_dashboards_not_in_list(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

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

What happens when a user attempts to update a pre-built dashboard, or delete one?

Copy link
Contributor Author

@edwardgou-sentry edwardgou-sentry Oct 23, 2025

Choose a reason for hiding this comment

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

We'll be locking down these dashboards so they can't be edited or deleted by users. Will be adding this in a follow up PR!

@getsentry getsentry deleted a comment from cursor bot Oct 23, 2025
Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@edwardgou-sentry edwardgou-sentry merged commit e30b8e7 into master Oct 23, 2025
69 of 70 checks passed
@edwardgou-sentry edwardgou-sentry deleted the egou/feat/prebuilt-dashboard-sync-backend branch October 23, 2025 15:43
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.

3 participants