feat(logs): admin-gated settings UI for the person pivot attribute#61301
feat(logs): admin-gated settings UI for the person pivot attribute#61301DanielVisca wants to merge 3 commits into
Conversation
|
Size Change: +9.54 kB (+0.01%) Total Size: 81.1 MB 📦 View Changed
ℹ️ View Unchanged
|
Adds a single-field settings panel under Environment > Logs > "Person pivot attribute" that lets admins change `logs_distinct_id_attribute_key` without `curl`-ing the API. Also wires a small gear-icon link from the existing scope hint on the person profile Logs tab so the setting is discoverable from where its effect is visible. Frontend gated at admin via the canonical `useRestrictedArea` pattern (matches `DefaultReleaseConditions`, `PersonDisplayNameProperties`, etc. — all team-affecting settings panels). Backend stays at `TeamMemberLightManagementPermission` to match `default_release_conditions` and the established backend-permissive + frontend-restrictive split that keeps API automations simple. The gear icon is always visible (default and customised cases) so the setting is discoverable on the default; the text only mentions the override when the key is non-default. Plan: see flickering-humming-honey.md — Phase 1 surveyed every comparable team-config setting (`path_cleaning_filters`, `test_account_filters`, `session_recording_*`, `default_release_conditions`, etc.) and found zero precedent for a single-field inline form editing a team-level value from a feature scene. The canonical pattern is "gear-icon link to settings page", which is what this implements. Generated-By: PostHog Code Task-Id: a0cd1bfc-9b19-4b30-9123-6488d22b3f6a
bc40f09 to
1e39656
Compare
There was a problem hiding this comment.
No showstoppers — pure frontend settings UI change that is admin-gated, feature-flagged, and connects to an existing backend endpoint. The LogsConfig type already included the field, double-submission is guarded, and access control is correctly enforced.
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
frontend/src/scenes/settings/SettingsMap.tsx:701-711
The description is rendered as a plain `{x.description}` string node in the Settings component (no markdown processing), so the backtick characters around `posthogDistinctId` will appear literally in the UI as `` `posthogDistinctId` `` rather than as formatted code. Since `description` accepts `JSX.Element | string`, the fix is to use JSX with a `<code>` tag and add a `searchDescription` string for the search index (which already uses `typeof setting.description === 'string' ? setting.description : ''`).
```suggestion
{
id: 'logs-distinct-id-attribute-key',
title: 'Person pivot attribute',
description: (
<>
Which OTel log attribute we match against a person's distinct_ids to surface logs on their
person profile. Defaults to <code>posthogDistinctId</code> — the key the JavaScript and React
Native SDKs auto-attach. Override only if your pipeline emits the person identifier under a
different key.
</>
),
searchDescription:
"Which OTel log attribute we match against a person's distinct_ids to surface logs on their person profile. Defaults to posthogDistinctId — the key the JavaScript and React Native SDKs auto-attach. Override only if your pipeline emits the person identifier under a different key.",
component: <LogsDistinctIdAttributeKey />,
flag: 'LOGS_SETTINGS',
keywords: ['log', 'person', 'distinct', 'attribute', 'pivot', 'profile', 'link'],
},
```
Reviews (1): Last reviewed commit: "feat(logs): admin-gated settings UI for ..." | Re-trigger Greptile |
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.
There was a problem hiding this comment.
Pure frontend settings UI addition: admin-gated, feature-flagged, double-submission guarded, and the previously raised inline comment about literal backtick rendering in descriptions was addressed with proper JSX using a <code> element. No backend, data model, or API contract changes.
Renames the new setting from "Person pivot attribute" to "Link to
person" to mirror the public docs page title ("Link logs to a person"
at /docs/logs/link-person) and the sibling sidebar entry "Link Session
Replay". The new wording leans on PostHog's "link logs to … " framing
that users already encounter in the docs and the related-replay link.
- SettingsMap.tsx: title rename, description reworded to lead with
"the log attribute PostHog reads to identify which person a log
belongs to" (plainer than the previous "pivot" phrasing). Keeps the
bot-added JSX description + searchDescription split.
- PersonLogsTab.tsx: gear-icon tooltip updated to match.
Generated-By: PostHog Code
Task-Id: a0cd1bfc-9b19-4b30-9123-6488d22b3f6a
New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.
|
Review agent failed — check the workflow run and re-apply the label to retry. |
There was a problem hiding this comment.
Pure frontend settings UI addition: admin-gated, feature-flagged, double-submission guarded, and the previously raised inline comment about literal backtick rendering was addressed with proper JSX using a <code> element. No backend, data model, or API contract changes.
Problem
We shipped the person profile Logs tab with a team-configurable
logs_distinct_id_attribute_key(the OTel log attribute we match against a person's distinct_ids to pivot logs onto a profile). Today it's API-only — teams have to `PATCH /api/projects//logs_config/` with a personal API key to change it from the default `posthogDistinctId`. The product PR (#61008) added a small muted hint on the person Logs tab when the key is non-default, but no in-app way to edit it.This adds a single-field settings panel and a discoverable link from the tab.
Changes
New settings panel under Environment → Logs → "Person pivot attribute" (
frontend/src/scenes/settings/environment/LogsDistinctIdAttributeKey.tsx):LemonInputfor the attribute key, plus a Save buttonuseRestrictedArea({ scope: RestrictionScope.Project, minimumAccessLevel: TeamMembershipLevel.Admin })— both the input and the Save button show a restricted-reason tooltip for non-admins. MirrorsPersonDisplayNameProperties.tsx:17-20exactly.updateLogsConfigloader added to the existinglogsConfigLogic(PATCHesapi/projects/<id>/logs_config/and updateslogsConfigstate in place).Discoverable link from the feature page (
frontend/src/scenes/persons/PersonLogsTab.tsx):IconGearLemonButtonto the existing scope hint, linking tourls.settings('environment-logs', 'logs-distinct-id-attribute-key')PathCleaningFilter.tsx:47-53andTestAccountFiltersSwitch.tsx:31-38precedentHow did you test this code?
I'm an agent (PostHog Code / Claude Opus 4.7). The user reviewed the plan before implementation (`flickering-humming-honey.md`). Verified:
No backend changes. No tests planned — the panel matches the shape of every other single-field settings component (none of which have per-component tests). The underlying API + serializer is covered by
posthog/api/test/test_team_logs_config.py.Automatic notifications
Docs update
The customer-facing concept doc (
docs/logs/link-person) already mentions the override capability and the API; the published version inposthog.com(PR #17207) doesn't need an update for this — the configurable key is already documented, this just adds the UI affordance. Could note "Change in Environment Settings → Logs" as a follow-up to that page once this merges.🤖 Agent context
PostHog Code (Opus 4.7). The user asked two precedent questions before implementation:
Is there precedent for inline editing of a team-level config on the feature page (vs. the settings page)? Phase 1 exploration found zero precedent for a single-field inline form editing a team-level value from a feature scene. Canonical pattern is gear-icon-links-to-settings (path cleaning, test account filters, etc.). Inline editing exists only in the experiments stats modal — but that edits per-experiment fields, not the team default. The plan picked the dominant precedent.
What permission should gate it? Every team-affecting settings panel in
frontend/src/scenes/settings/environment/uses `useRestrictedArea({ scope: Project, minimumAccessLevel: Admin })`. Zero usages of `TeamMembershipLevel.Member` anywhere in the frontend. Backend stays at the existing `TeamMemberLightManagementPermission` (matches `default_release_conditions` — same Light-backend + Admin-frontend split). The backend-permissive + frontend-restrictive pattern keeps API automations simple while preventing accidental UI clicks; that's the established PostHog convention.Companion PRs landed previously: #60537 (Logs tab on person profile), #60536 (team-configurable attribute key backend), #60967 (URL dual-registration fix), #61008 (architectural pinned-filter fix + scope hint).
Created with PostHog Code