Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 35 additions & 15 deletions src/sentry/seer/endpoints/organization_seer_onboarding_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@

import logging

from rest_framework import status
from rest_framework.request import Request
from rest_framework.response import Response

from sentry import options
from sentry import features, options
from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
from sentry.api.base import cell_silo_endpoint
from sentry.api.bases.organization import OrganizationEndpoint
from sentry.constants import ObjectStatus
from sentry.integrations.services.integration import integration_service
from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.options.project_option import ProjectOption
from sentry.models.organization import Organization
from sentry.models.project import Project
from sentry.models.repositorysettings import RepositorySettings
from sentry.ratelimits.config import RateLimitConfig
from sentry.seer.autofix.constants import AutofixAutomationTuningSettings
from sentry.seer.autofix.utils import bulk_get_project_preferences
from sentry.seer.models.project_repository import SeerProjectRepository
from sentry.seer.models.seer_api_models import SeerApiError
from sentry.types.ratelimit import RateLimit, RateLimitCategory

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -50,22 +53,29 @@
).exists()


def is_autofix_enabled(organization_id: int) -> bool:
def is_autofix_enabled(organization: Organization) -> bool:
"""
Check if autofix/RCA is enabled for any active project in the organization,
ie, if any project has sentry:autofix_automation_tuning not set to "off" or None.
ie, if any project has repositories configured in Seer preferences.
"""
return (
ProjectOption.objects.filter(
project__organization_id=organization_id,
project__status=ObjectStatus.ACTIVE,
key="sentry:autofix_automation_tuning",
)
.exclude(value=AutofixAutomationTuningSettings.OFF.value)
.exclude(value__isnull=True)
.exists()
if features.has("organizations:seer-project-settings-read-from-sentry", organization):
return SeerProjectRepository.objects.filter(
project__organization_id=organization.id, project__status=ObjectStatus.ACTIVE
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If repo is disabled/hidden its SeerProjectRepositoryRow will be deleted, so we don't need to filter by repo status here.

).exists()

project_ids = list(
Project.objects.filter(
organization_id=organization.id,
status=ObjectStatus.ACTIVE,
).values_list("id", flat=True)
)

if not project_ids:
return False

preferences = bulk_get_project_preferences(organization.id, project_ids)
return any(pref and pref.get("repositories") for pref in preferences.values())


@cell_silo_endpoint
class OrganizationSeerOnboardingCheck(OrganizationEndpoint):
Expand All @@ -86,11 +96,21 @@
}
)

def get(self, request: Request, organization: Organization) -> Response:
"""Check if the organization has completed Seer onboarding/configuration."""
try:
autofix_enabled = is_autofix_enabled(organization)
except SeerApiError as e:
logger.exception(
"seer.onboarding_check.autofix_check_error",
extra={"organization_id": organization.id, "status_code": e.status},
)
return Response(
{"detail": "Failed to check autofix status"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)

Check warning on line 111 in src/sentry/seer/endpoints/organization_seer_onboarding_check.py

View check run for this annotation

@sentry/warden / warden: sentry-backend-bugs

JSONDecodeError from malformed Seer API response not caught

The endpoint catches `SeerApiError` from `is_autofix_enabled()`, but `bulk_get_project_preferences()` can also raise `orjson.JSONDecodeError` on line 884 of utils.py if the Seer API returns malformed JSON (e.g., HTML error page, truncated response). This would bypass the error handler and return a generic 500 instead of the intended error response.
has_scm_integration = has_supported_scm_integration(organization.id)
code_review_enabled = is_code_review_enabled(organization.id)
autofix_enabled = is_autofix_enabled(organization.id)
needs_config_reminder = is_in_seer_config_reminder_list(organization)
is_seer_configured = has_scm_integration and (code_review_enabled or autofix_enabled)

Expand Down
Loading
Loading