mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
716 files rewritten, 30 renamed, same family mapping as the frontend pass.
Held back, and each for a reason rather than by oversight:
db_table values insights_hogfunction, insights_hogflow,
insights_hogfunctiontemplate, hogflow_templates.
Renaming a table is ALTER TABLE, so it ships as a
migration with the raw SQL in nodejs that names it.
hog_invocation_results a Datastore table with Kafka engine tables on it
products/review_hog the module path is the Django app path; moving it
moves app_label and every migration is recorded under
(app_label, name). That is the same history break as
renaming a migration file, one level up.
*/migrations/* five files, untouched
whogho an integration vendor
Checked: 395 of 397 changed Python files compile. The two that do not —
insightsql/database/database.py and temporal/schedule.py — fail identically at
origin/main under the same interpreter, because they use `type X = ...` and
`except*`, which need the 3.13 this repo pins and not the 3.9 doing the check.
Running the check against the original is what told those apart from a real
break.
Co-authored-by: Hanzo Dev <[email protected]>
84 lines
3.9 KiB
Python
84 lines
3.9 KiB
Python
"""Task visibility filters.
|
|
|
|
Kept out of the API module so import-light consumers (the file-system registration in
|
|
insights.api.file_system.registrations, which loads at django.setup()) don't pull the whole
|
|
tasks API surface — its module-scope imports reach jsonschema and the modal SDK.
|
|
"""
|
|
|
|
from django.db.models import Q
|
|
|
|
from products.tasks.backend.models import Channel, Task
|
|
|
|
# Origin products whose tasks are team-scoped rather than personal: every team member
|
|
# can view them regardless of who created them.
|
|
# - SIGNAL_REPORT / SIGNALS_SCOUT: pipeline artifacts attached to a system-picked
|
|
# `created_by` so the agent can mint an OAuth token, but they are not personal.
|
|
# - ONBOARDING: the "Set up Insights" wizard task. Its `created_by` is the real person who
|
|
# went through onboarding (not a system pick), but we surface it team-wide so anyone on
|
|
# the team can see and pick up the setup, not just whoever happened to start it.
|
|
# - Desk: support-desk Code threads. The task is pinned to the support ticket via a
|
|
# shared ticket tag, so any agent opening the ticket resumes the same thread — it must
|
|
# be viewable by the whole team, not just the agent who started it.
|
|
TEAM_VISIBLE_ORIGIN_PRODUCTS = [
|
|
Task.OriginProduct.SIGNAL_REPORT,
|
|
Task.OriginProduct.SIGNALS_SCOUT,
|
|
Task.OriginProduct.ONBOARDING,
|
|
Task.OriginProduct.Desk,
|
|
]
|
|
|
|
# Origin products whose tasks are team-readable but stay creator-driven, like
|
|
# public-channel tasks: teammates can open the task and read what the agent did or
|
|
# asked, but runs execute with the creator's credentials (oauth.py mints tokens from
|
|
# `task.created_by`), so edits, runs, and agent commands stay with the creator.
|
|
# - EXPERIMENTS: flag-cleanup tasks opened when an experiment ends. The experiment
|
|
# (and the task's status on it) is team-visible, so any team member should be able
|
|
# to open the task, not just whoever clicked "End experiment".
|
|
TEAM_READABLE_ORIGIN_PRODUCTS = [
|
|
*TEAM_VISIBLE_ORIGIN_PRODUCTS,
|
|
Task.OriginProduct.EXPERIMENTS,
|
|
]
|
|
|
|
|
|
def task_control_q(user_id: int | None) -> Q:
|
|
"""Filter for tasks the given user may mutate or drive (edits, runs, agent commands).
|
|
|
|
A task is controllable if:
|
|
- its creator matches `user_id`, or
|
|
- it has no creator at all (legacy unowned tasks remain visible to any
|
|
team member — they cannot be executed in any case because oauth.py
|
|
requires `task.created_by` to mint OAuth tokens), or
|
|
- its `origin_product` is one of `TEAM_VISIBLE_ORIGIN_PRODUCTS`, i.e. a
|
|
team-scoped artifact (signals, onboarding) any team member may pick up.
|
|
|
|
Deliberately narrower than ``task_visibility_q``: public-channel tasks are
|
|
team-readable but stay creator-driven — seeing a teammate's task in a feed
|
|
must not allow editing it, starting runs, or messaging its agent (thread
|
|
forwarding is the explicit, author-only path for that).
|
|
"""
|
|
return Q(created_by_id=user_id) | Q(created_by__isnull=True) | Q(origin_product__in=TEAM_VISIBLE_ORIGIN_PRODUCTS)
|
|
|
|
|
|
def task_visibility_q(user_id: int | None) -> Q:
|
|
"""Filter for tasks visible (readable) to the given user.
|
|
|
|
Everything controllable per ``task_control_q``, plus team-readable origins
|
|
and tasks in a public channel: channel feeds are multiplayer, so every team
|
|
member sees every task filed there. Personal-channel ("#me") tasks stay
|
|
creator-only via the control rules.
|
|
"""
|
|
return (
|
|
task_control_q(user_id)
|
|
| Q(origin_product__in=TEAM_READABLE_ORIGIN_PRODUCTS)
|
|
| Q(channel__channel_type=Channel.ChannelType.PUBLIC, channel__deleted=False)
|
|
)
|
|
|
|
|
|
def task_run_visibility_q(user_id: int | None) -> Q:
|
|
"""`task_visibility_q` traversed via the `task` FK on TaskRun / TaskAutomation."""
|
|
return (
|
|
Q(task__created_by_id=user_id)
|
|
| Q(task__created_by__isnull=True)
|
|
| Q(task__origin_product__in=TEAM_READABLE_ORIGIN_PRODUCTS)
|
|
| Q(task__channel__channel_type=Channel.ChannelType.PUBLIC, task__channel__deleted=False)
|
|
)
|