Files
zeekay eef5eeff1d close the last of ee, and refuse the name outright
Three things the earlier ee work left open.

THE GATE COULD STILL PASS AN ee IMPORT. check-imports-are-committed carried `ee`
inside FIRST_PARTY, so the verdict depended on whether the import RESOLVED —
which is only false while the tree happens to be absent. Commit an ee/ and the
check goes green on the very thing it exists to stop. FIRST_PARTY answers "is
this committed"; `ee` is not missing, it is refused, so it is now its own
question and the answer does not consult the filesystem.

Measured both ways rather than asserted. With ee/anything.py staged and a file
importing it, this version exits 1 and the resolution version, run against that
same tree, exits 0.

THE LAST ee REFERENCES. Nine @patch("ee.sqs.SQSProducer.get_sqs_producer") in
test_usage_report.py — string targets, so no import scan sees them; they raise
ModuleNotFoundError only when the test runs. usage_report.py sets producer=None
unconditionally, so the SQS send cannot happen here: the three tests whose
subject was the send are gone, and the five whose subject is the filtering
telemetry keep their assertions with only the dead patch removed.

Also the ones that were never imports at all: LOGIN_METHODS naming
ee.api.authentication backends that are not in AUTHENTICATION_BACKENDS (this
deployment federates through Hanzo IAM and nothing else), five ee receivers in
setup_receivers_baseline.txt, create_ch_migration writing into
"ee/datastore/migrations" — a directory that is not there, so the command
raised FileNotFoundError instead of creating anything — and comments still
pointing readers at ee/ paths for code that now lives here.

DROPPING ("ee", ...) FROM A MIGRATION ALSO DROPPED ITS ORDERING. That dependency
put those migrations after the ee migration that created the roles. Without a
replacement a fresh database fails on `relation "ee_role" does not exist`,
proven by running migrate against one; each now depends on
insights.0002_managed_tables, which is what creates those tables here.

Dockerfile.node named the upstream package it resolves to, which debrand --check
refuses; the override in pnpm-workspace.yaml already says which package it is.
2026-08-08 15:06:15 -07:00

71 lines
3.0 KiB
Python

from typing import Any
from django.db import transaction
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from insights.models.integration import Integration
from insights.models.user_integration import UserIntegration
@receiver(post_save, sender=UserIntegration)
@receiver(post_delete, sender=UserIntegration)
def invalidate_repo_list_on_user_github_change(sender: Any, instance: UserIntegration, **kwargs) -> None:
if instance.kind != UserIntegration.IntegrationKind.GITHUB:
return
# Deferred: api.py imports the temporal.ai workflows at module scope.
# This receiver is wired from AppConfig.ready(), so a module-level import would drag that onto
# every process's startup path.
from products.slack_app.backend.api import _invalidate_user_repo_list_cache # noqa: PLC0415
_invalidate_user_repo_list_cache(instance.user_id)
@receiver(post_save, sender=Integration)
def onboard_slack_inbox_on_install(sender: Any, instance: Integration, created: bool, **kwargs) -> None:
"""Fresh Slack install -> enqueue the #insights-inbox onboarding Temporal workflow on commit (the
enqueue runs inline; the workflow itself runs on a Temporal worker). Gated on ``channels:manage``.
Re-auth uses update_or_create (created=False), so only first installs onboard."""
if not created or instance.kind != "slack":
return
# Deferred: keep the import lazy since this receiver is wired from AppConfig.ready().
from products.slack_app.backend.inbox_channel import has_inbox_scopes # noqa: PLC0415
if not has_inbox_scopes(instance):
return
integration_id = instance.id
transaction.on_commit(lambda: _start_inbox_onboarding_workflow(integration_id))
def _start_inbox_onboarding_workflow(integration_id: int) -> None:
# Deferred imports keep the Temporal stack off the signals (AppConfig.ready) import path.
import asyncio
from django.conf import settings
import structlog
from temporalio.common import WorkflowIDReusePolicy
from insights.temporal.ai.slack_app.insights_slack_inbox_onboarding import ( # noqa: PLC0415
InsightsSlackInboxOnboardingWorkflow,
)
from insights.temporal.ai.slack_app.types import InsightsSlackInboxOnboardingInputs # noqa: PLC0415
from insights.temporal.common.client import sync_connect # noqa: PLC0415
log = structlog.get_logger(__name__)
try:
client = sync_connect()
asyncio.run(
client.start_workflow(
InsightsSlackInboxOnboardingWorkflow.run,
InsightsSlackInboxOnboardingInputs(integration_id=integration_id),
id=f"insights-slack-inbox-onboarding-{integration_id}",
task_queue=settings.TASKS_TASK_QUEUE,
id_reuse_policy=WorkflowIDReusePolicy.ALLOW_DUPLICATE,
)
)
except Exception:
log.warning("slack_app_inbox_onboarding_dispatch_failed", integration_id=integration_id, exc_info=True)