mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
Every first-party Python caller and test now names the mount the API actually answers on. Mechanical: URL literals only, and only where the /api/ was ours -- a preceding word character means it was a module path like insights/api/ or a third-party host like slack.com/api/, and those are untouched. Left saying /api/, each for a reason rather than for safety: - products/warehouse_sources/.../sources/** is a catalogue of vendor endpoints - services/llm-gateway deploys separately and is under a code freeze, so moving its two calls would break it during the skew - the mcp_store and Slack/Teams redirect_uris are registered with third parties and must byte-match what was registered - the Wizard and Raycast client-metadata paths are OAuth client_ids - /api/surveys and /api/feature_flag/local_evaluation are SDK aliases the ingress routes to the Rust fleets, held by released SDK versions Test URLconfs moved with the requests that call them, and the Datastore user-selection fixtures now carry the leading slash that request.path has.
74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
from django.apps import AppConfig
|
|
|
|
|
|
class NotebooksConfig(AppConfig):
|
|
default_auto_field = "django.db.models.BigAutoField"
|
|
name = "products.notebooks.backend"
|
|
label = "notebooks"
|
|
|
|
def ready(self) -> None:
|
|
from insights.api.file_system.deletion import (
|
|
register_file_system_type,
|
|
register_post_delete_hook,
|
|
register_post_restore_hook,
|
|
)
|
|
from insights.helpers.impersonation import is_impersonated
|
|
from insights.models.activity_logging.activity_log import Change
|
|
from insights.models.user import User
|
|
|
|
# Lives in its own module: the API module's imports reach the kernel runtime and the
|
|
# tasks sandbox (modal SDK), which must stay off the django.setup() path.
|
|
from products.notebooks.backend.activity_logging import log_notebook_activity
|
|
|
|
register_file_system_type(
|
|
"notebook",
|
|
"notebooks",
|
|
"Notebook",
|
|
lookup_field="short_id",
|
|
undo_message="Send PATCH /v1/projects/@current/notebooks/{id} with deleted=false.",
|
|
)
|
|
|
|
def _post_delete(context, notebook):
|
|
organization = context.organization
|
|
if not organization:
|
|
return
|
|
team = context.team
|
|
team_id = getattr(team, "id", None) if team is not None else None
|
|
if not isinstance(team_id, int):
|
|
return
|
|
user = context.user
|
|
if not isinstance(user, User):
|
|
return
|
|
log_notebook_activity(
|
|
activity="deleted",
|
|
notebook=notebook,
|
|
organization_id=organization.id,
|
|
team_id=team_id,
|
|
user=user,
|
|
was_impersonated=is_impersonated(context.request),
|
|
)
|
|
|
|
def _post_restore(context, notebook):
|
|
organization = context.organization
|
|
if not organization:
|
|
return
|
|
team = context.team
|
|
team_id = getattr(team, "id", None) if team is not None else None
|
|
if not isinstance(team_id, int):
|
|
return
|
|
user = context.user
|
|
if not isinstance(user, User):
|
|
return
|
|
log_notebook_activity(
|
|
activity="restored",
|
|
notebook=notebook,
|
|
organization_id=organization.id,
|
|
team_id=team_id,
|
|
user=user,
|
|
was_impersonated=is_impersonated(context.request),
|
|
changes=[Change(type="Notebook", action="changed", field="deleted", before=True, after=False)],
|
|
)
|
|
|
|
register_post_delete_hook("notebook", _post_delete)
|
|
register_post_restore_hook("notebook", _post_restore)
|