feat(tasks): add staff filter to see all team tasks - #70775
Conversation
Tasks are visibility-gated per creator: a task filed in a personal channel (or none) is invisible to teammates, so listing it or opening it by ID returns 404. This adds a staff escape hatch for support and debugging. - List: new `all_team_tasks` query param, honored only for staff (or internal-debug teams), bypasses the per-user visibility filter. Surfaced as an opt-in "All team tasks (staff)" option in the filter menu next to the search bar; not selected by default. - Detail + run logs: the existing `?ph_debug=true` read opt-in now authorizes staff users on any team, not just the internal-debug team, so clicking through from the all-team list loads the task and its logs. Writes stay creator-scoped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Generated-By: PostHog Code Task-Id: 7e47d2df-b3f5-49b2-81ba-1ad528a27b47
|
Hey @skoob13! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
🤖 CI report
|
| File | Size | Δ vs base |
|---|---|---|
render-query/src/render-query/render-query.js |
21.24 MiB | 🔺 +5.4 KiB (+0.0%) |
exporter/src/lib/components/ActivityLog/describers.js |
128.4 KiB | 🔺 +1.2 KiB (+1.0%) |
posthog-app/src/lib/components/ActivityLog/describers.js |
131.3 KiB | 🔺 +1.2 KiB (+0.9%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.21 MiB · 22 files | no change | ███░░░░░░░ 28.2% of 4.29 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
8.12 MiB · 2,975 files | 🔺 +2.6 KiB (+0.0%) | █████████░ 87.8% of 9.25 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 280.3 KiB | ../node_modules/.pnpm/posthog-js@1.400.0/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 234.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 222.8 KiB | ../node_modules/.pnpm/posthog-js@1.400.0/node_modules/posthog-js/dist/module.js |
| 164.0 KiB | src/queries/validators.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.9 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
⚠️ Dist folder size — 🔺 +196.4 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1285.01 MiB · 🔺 +196.4 KiB (+0.0%)
⚠️ MCP snapshots — 1 updated (1 modified, 0 added, 0 deleted)
Snapshots: MCP unit test snapshots updated
Changes: 1 snapshots (1 modified, 0 added, 0 deleted)
What this means:
- Snapshots have been automatically updated to match current output
Next steps:
- Review the changes to ensure they're intentional
- If unexpected, investigate what caused the output to change
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
|
Reviews (1): Last reviewed commit: "chore: update OpenAPI generated types" | Re-trigger Greptile |
The list rows navigate via urls.taskDetail() directly rather than through openTask, so the ph_debug opt-in never reached the detail page — a staff user could see a teammate's task in the "All team tasks" view but still 404 on click. Centralize the opt-in as a taskDetailQueryParams selector and apply it to both the row Link/push and openTask. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Generated-By: PostHog Code Task-Id: 7e47d2df-b3f5-49b2-81ba-1ad528a27b47
The ph_debug query-param opt-in was too fragile to gate staff reads: it has to be threaded through every read request and preserved across navigation, but the SSE run-log stream carries no query param, so staff still hit 404s opening a teammate's task or its logs. - Backend: staff users may READ any task/run on their team unconditionally (no opt-in). Internal -debug teams keep the explicit ?ph_debug=true path. Writes stay creator-scoped. Run-view bypass now covers all read-only actions (adds the artifacts read endpoints). - Frontend: hide the composer when a staff user views a task they don't own — read-only viewing (the stream still flows live). Removes the now-unneeded ph_debug navigation plumbing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Generated-By: PostHog Code Task-Id: 7e47d2df-b3f5-49b2-81ba-1ad528a27b47
The living-artifacts run-read viewset kept its own gate that only granted access on an internal-debug team (id 1/2) via ?ph_debug=true, so a staff user viewing a run on any other team's task 404'd on that endpoint. Route it through the shared staff read bypass like the main run viewset. Task/run/channel reads were already team-agnostic for staff. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Generated-By: PostHog Code Task-Id: 7e47d2df-b3f5-49b2-81ba-1ad528a27b47
|
✅ Visual changes approved by @sortafreel — baseline updated in 1 changed. |
1 updated Run: 6490c05c-1748-4cb3-9513-b4de8ceda88b Co-authored-by: sortafreel <354488+sortafreel@users.noreply.github.com>
Problem
Tasks are visibility-gated per creator, not per team. A task filed in a personal channel (or no channel) is only visible to whoever created it — so a teammate who sees the task ID (e.g. in the DB) gets a 404 when they open it in the UI, and can't check its logs. Staff need a way to view any task on a team for support and debugging. Raised in a Slack thread on the new Tasks UI.
Changes
all_team_tasksquery param onGET /tasks/. Honored only for staff users (and internal-debug teams), it bypasses the per-user visibility filter. Surfaced as an opt-in "All team tasks (staff)" radio option in the filter menu beside the search bar — not selected by default. Non-staff requests are ignored server-side.?ph_debug=trueread opt-in now authorizes staff users on any team (previously only the internal-debug team). Opening a task from the all-team view carries the opt-in so the detail page and its run logs load. Writes stay creator-scoped.How did you test this code?
Added
TestTaskStaffVisibilityBypassinproducts/tasks/backend/tests/test_api.pycovering the new behavior that no existing test did: staff can list other members' tasks only withall_team_tasks=true(opt-in, off by default), non-staff requests with the flag are ignored, staff can retrieve a teammate's task/runs with?ph_debug=true(and still 404 without it), and writes remain 404 for non-owners.The local dev stack (Postgres) isn't available in this environment, so I could not run the DB-backed tests or
hogli build:openapihere — CI will run both. The change is import- and lint-clean (ruff check/ruff formatpass). FrontendTaskListParamsis hand-maintained and already updated; the only OpenAPI drift is the additiveall_team_tasksquery param, which codegen will regenerate.Docs update
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Authored by the PostHog Slack app from a Slack thread. Skills invoked:
/improving-drf-endpoints(viewset + query serializer),/writing-tests(test value gate), and the/adopting-generated-api-typesguidance was considered —api.tasksis hand-rolled soTaskListParamswas updated by hand rather than switching to the generated client.Key decisions: reused the existing
ph_debugread plumbing (which already threads throughapi.tasks.getandapi.tasks.runs.get) for the detail/run path rather than inventing a second param there, and kept the list filter as its ownall_team_tasksparam since the menu drives it as persistent UI state. Server-side re-checksis_staffon every path so a client can't forge the flag.build:openapicouldn't run locally (no DB); flagging so a reviewer/codegen regenerates the additive spec change.Created with PostHog from a Slack thread