feat(customer-analytics): add default pinned account properties - #108076
arthurdedeus wants to merge 11 commits into
Conversation
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
Game on, robots! @veria-ai @greptile-apps @parameterai |
|
Took a look at the diff — the new |
🤖 CI report
|
| Function | Location | Complexity | Limit |
|---|---|---|---|
errors |
products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/customPropertyDefinitionsLogic.ts:950 |
18 | 10 |
submit |
products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/customPropertyDefinitionsLogic.ts:984 |
17 | 10 |
openEditModal |
products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/customPropertyDefinitionsLogic.ts:1311 |
15 | 10 |
DefaultPinnedAccountProperties |
products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/DefaultPinnedAccountProperties.tsx:12 |
14 | 10 |
loadSelectedTableColumns |
products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/customPropertyDefinitionsLogic.ts:845 |
12 | 10 |
✅ Duplication (Python) — clean
New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
✅ Duplication (TypeScript) — clean
New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
⚠️ Bundle size — 🔺 +870 B (+0.0%)
Uncompressed size of every built .js bundle, compared against the base branch.
Total: 68.97 MiB · 🔺 +870 B (+0.0%)
No file changed by more than 1000 B.
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.58 MiB · 22 files | no change | █████████░ 85.8% of 1.84 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
3.52 MiB · 629 files | no change | █████████░ 87.4% of 4.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.35 MiB · 2,339 files | no change | █████████░ 88.1% of 8.34 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/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 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
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts 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
🟢 [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/index.tsx |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 854 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 301.8 KiB | ../node_modules/.pnpm/posthog-js@1.434.14_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 216.9 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 |
| 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 |
| 100.5 KiB | src/lib/api.ts |
| 88.5 KiB | src/products.tsx |
| 69.4 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 40.1 KiB | src/lib/utils/eventUsageLogic.ts |
| 38.7 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
| 28.4 KiB | src/scenes/scenes.ts |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 301.8 KiB | ../node_modules/.pnpm/posthog-js@1.434.14_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 272.3 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 216.9 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 |
| 153.7 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 |
| 100.5 KiB | src/lib/api.ts |
| 98.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 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 |
| 88.5 KiB | src/products.tsx |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.16 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.16 MiB · 19 files | no change | ████░░░░░░ 37.8% of 5.72 MiB |
| Deferred (lazy) | 2.10 MiB · 44 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.2 KiB | no change | █░░░░░░░░░ 6.0% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 805.5 KiB | dist/toolbar/toolbar-app-ZATDHZQQ.css |
| 651.7 KiB | dist/toolbar/chunk-chunk-7ZORLPSY.js |
| 259.4 KiB | dist/toolbar/chunk-chunk-2FGAEFTI.js |
| 138.3 KiB | dist/toolbar/chunk-chunk-UA3V2PCC.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 75.2 KiB | dist/toolbar/toolbar-app-SD4VQXWA.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-63EWNJRZ.js |
| 21.0 KiB | dist/toolbar/chunk-chunk-F5GDSM5D.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +144.6 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 947.93 MiB · 🔺 +144.6 KiB (+0.0%)
ℹ️ MCP UI apps size — 33 app(s), 17633.1 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 597.9 KB | 199.2 KB |
| action | 454.1 KB | 199.2 KB |
| action-list | 564.2 KB | 199.2 KB |
| cohort | 453.1 KB | 199.2 KB |
| cohort-list | 563.2 KB | 199.2 KB |
| email-template | 452.9 KB | 199.2 KB |
| error-details | 469.6 KB | 199.2 KB |
| error-issue | 454.5 KB | 199.2 KB |
| error-issue-list | 564.8 KB | 199.2 KB |
| experiment | 561.3 KB | 199.2 KB |
| experiment-list | 564.9 KB | 199.2 KB |
| experiment-results | 566.3 KB | 199.2 KB |
| feature-flag | 566.8 KB | 199.2 KB |
| feature-flag-list | 570.5 KB | 199.2 KB |
| feature-flag-testing | 457.3 KB | 199.2 KB |
| inline-scan | 453.6 KB | 199.2 KB |
| insight-actors | 562.3 KB | 199.2 KB |
| invite-email-preview | 452.3 KB | 199.2 KB |
| llm-costs | 559.3 KB | 199.2 KB |
| session-recording | 455.3 KB | 199.2 KB |
| survey | 454.7 KB | 199.2 KB |
| survey-global-stats | 561.9 KB | 199.2 KB |
| survey-list | 564.9 KB | 199.2 KB |
| survey-stats | 561.9 KB | 199.2 KB |
| trace-span | 453.5 KB | 199.2 KB |
| trace-span-list | 564.1 KB | 199.2 KB |
| vision-observation-list | 563.3 KB | 199.2 KB |
| workflow | 453.4 KB | 199.2 KB |
| workflow-list | 563.5 KB | 199.2 KB |
| loops-review | 457.8 KB | 199.2 KB |
| query-results | 774.1 KB | 199.2 KB |
| render-ui | 858.1 KB | 199.2 KB |
| visual-review-snapshots | 457.9 KB | 199.2 KB |
⚠️ Backend coverage — 99.0% of changed backend lines covered — 1 uncovered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ████████████████████ 99.0% (171 / 172)
| File | Patch | Uncovered changed lines |
|---|---|---|
products/customer_analytics/backend/facade/account_property_pins.py |
85.7% | 9 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 36614227385 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
warehouse_sources_queue |
██░░░░░░░░░░░░░░░░░░ 10.5% |
187 / 1,777 |
platform_features |
██░░░░░░░░░░░░░░░░░░ 12.1% |
7 / 58 |
demo |
███████████░░░░░░░░░ 52.8% |
1,411 / 2,673 |
data_tools |
████████████░░░░░░░░ 61.2% |
90 / 147 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
aeo |
███████████████░░░░░ 76.3% |
617 / 809 |
batch_exports |
████████████████░░░░ 81.2% |
21,525 / 26,502 |
apm |
█████████████████░░░ 84.1% |
1,306 / 1,553 |
cdp |
██████████████████░░ 88.2% |
4,545 / 5,155 |
ml_inference |
██████████████████░░ 88.4% |
509 / 576 |
mcp_analytics |
██████████████████░░ 89.2% |
5,038 / 5,651 |
product_tours |
██████████████████░░ 89.3% |
1,331 / 1,491 |
dashboards |
██████████████████░░ 89.5% |
6,904 / 7,714 |
data_warehouse |
██████████████████░░ 90.0% |
14,027 / 15,589 |
notebooks |
██████████████████░░ 90.2% |
15,297 / 16,964 |
signals |
██████████████████░░ 90.2% |
57,836 / 64,097 |
cohorts |
██████████████████░░ 90.4% |
8,420 / 9,316 |
streamlit_apps |
██████████████████░░ 90.8% |
2,684 / 2,956 |
managed_warehouse |
██████████████████░░ 91.0% |
10,252 / 11,263 |
tasks |
██████████████████░░ 91.1% |
75,525 / 82,874 |
data_modeling |
██████████████████░░ 91.4% |
10,554 / 11,543 |
exports |
██████████████████░░ 91.6% |
9,680 / 10,562 |
engineering_analytics |
██████████████████░░ 91.7% |
11,032 / 12,030 |
ai_training |
██████████████████░░ 92.2% |
356 / 386 |
business_knowledge |
██████████████████░░ 92.2% |
7,684 / 8,330 |
conversations |
███████████████████░ 92.5% |
28,734 / 31,062 |
early_access_features |
███████████████████░ 92.6% |
1,332 / 1,439 |
managed_migrations |
███████████████████░ 92.7% |
1,581 / 1,705 |
visual_review |
███████████████████░ 92.8% |
9,247 / 9,969 |
stamphog |
███████████████████░ 92.8% |
8,109 / 8,742 |
canvas |
███████████████████░ 92.8% |
6,873 / 7,405 |
approvals |
███████████████████░ 93.0% |
3,974 / 4,271 |
mcp_registry |
███████████████████░ 93.1% |
1,670 / 1,794 |
notifications |
███████████████████░ 93.2% |
1,145 / 1,229 |
error_tracking |
███████████████████░ 93.2% |
16,359 / 17,547 |
surveys |
███████████████████░ 93.3% |
6,571 / 7,040 |
slack_app |
███████████████████░ 93.4% |
13,995 / 14,989 |
autoresearch |
███████████████████░ 93.6% |
8,481 / 9,061 |
context_layer |
███████████████████░ 93.9% |
3,415 / 3,638 |
web_analytics |
███████████████████░ 94.0% |
21,815 / 23,218 |
alerts |
███████████████████░ 94.0% |
8,570 / 9,114 |
billing_alerts |
███████████████████░ 94.1% |
2,094 / 2,226 |
mcp_store |
███████████████████░ 94.4% |
8,940 / 9,472 |
ai_observability |
███████████████████░ 94.5% |
24,473 / 25,896 |
workflows |
███████████████████░ 94.6% |
15,222 / 16,093 |
wizard |
███████████████████░ 94.7% |
6,150 / 6,496 |
reminders |
███████████████████░ 94.8% |
760 / 802 |
review_hog |
███████████████████░ 95.0% |
11,507 / 12,119 |
endpoints |
███████████████████░ 95.1% |
9,206 / 9,681 |
annotations |
███████████████████░ 95.1% |
817 / 859 |
customer_analytics |
███████████████████░ 95.2% |
25,708 / 27,011 |
legal_documents |
███████████████████░ 95.2% |
2,311 / 2,427 |
marketing_analytics |
███████████████████░ 95.3% |
19,566 / 20,528 |
posthog_ai |
███████████████████░ 95.3% |
2,488 / 2,610 |
experiments |
███████████████████░ 95.4% |
32,457 / 34,020 |
actions |
███████████████████░ 95.5% |
756 / 792 |
logs |
███████████████████░ 95.5% |
15,399 / 16,130 |
data_catalog |
███████████████████░ 95.6% |
4,402 / 4,606 |
tracing |
███████████████████░ 95.6% |
3,536 / 3,699 |
replay_vision |
███████████████████░ 95.6% |
27,675 / 28,939 |
growth |
███████████████████░ 95.7% |
11,228 / 11,734 |
messaging |
███████████████████░ 95.8% |
3,798 / 3,963 |
skills |
███████████████████░ 95.8% |
6,972 / 7,274 |
product_analytics |
███████████████████░ 96.0% |
28,470 / 29,647 |
access_control |
███████████████████░ 96.3% |
7,113 / 7,386 |
revenue_analytics |
███████████████████░ 96.4% |
1,876 / 1,946 |
user_interviews |
███████████████████░ 96.5% |
2,867 / 2,971 |
feature_flags |
███████████████████░ 96.5% |
25,588 / 26,509 |
warehouse_sources |
███████████████████░ 97.3% |
458,450 / 471,303 |
data_quality |
████████████████████ 97.6% |
7,587 / 7,774 |
links |
████████████████████ 97.9% |
234 / 239 |
security |
████████████████████ 98.0% |
1,286 / 1,312 |
metrics |
████████████████████ 98.0% |
4,084 / 4,166 |
analytics_platform |
████████████████████ 98.3% |
2,784 / 2,833 |
pulse |
████████████████████ 98.5% |
2,046 / 2,078 |
live_debugger |
████████████████████ 99.2% |
626 / 631 |
field_notes |
████████████████████ 99.4% |
172 / 173 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
⚠️ 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
⚠️ Django migration SQL — 1 new migration to review
We've detected new migrations on this PR. Review the SQL output for each migration:
products/customer_analytics/backend/migrations/0060_teamcustomeranalyticsconfig_default_pinned_properties.py
/opt/hostedtoolcache/Python/3.14.7/x64/lib/python3.14/site-packages/anyio/from_thread.py:119: SyntaxWarning: 'return' in a 'finally' block
return result
/opt/hostedtoolcache/Python/3.14.7/x64/lib/python3.14/site-packages/structlog/stdlib.py:1166: UserWarning: Remove `format_exc_info` from your processor chain if you want pretty exceptions.
ed = p(logger, meth_name, ed) # type: ignore[arg-type]
2026-09-29T18:48:14.759330Z [error ] Path must be a valid database or directory containing databases. [posthog.exceptions_capture] pid=9337 tid=139744523258752
Traceback (most recent call last):
File "/home/runner/work/posthog/posthog/posthog/geoip.py", line 15, in <module>
geoip: Optional[GeoIP2] = GeoIP2(cache=8)
~~~~~~^^^^^^^^^
File "/opt/hostedtoolcache/Python/3.14.7/x64/lib/python3.14/site-packages/django/contrib/gis/geoip2.py", line 116, in __init__
raise GeoIP2Exception(
"Path must be a valid database or directory containing databases."
)
django.contrib.gis.geoip2.GeoIP2Exception: Path must be a valid database or directory containing databases.
/opt/hostedtoolcache/Python/3.14.7/x64/lib/python3.14/site-packages/sshtunnel.py:1040: SyntaxWarning: 'return' in a 'finally' block
return (ssh_host,
/opt/hostedtoolcache/Python/3.14.7/x64/lib/python3.14/site-packages/langchain_core/_api/deprecation.py:27: UserWarning: Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater.
from pydantic.v1.fields import FieldInfo as FieldInfoV1
System check identified some issues:
WARNINGS:
?: (axes.W001) You are using the django-axes cache handler for login attempt tracking. Your cache configuration is however invalid and will not work correctly with django-axes. This can leave security holes in your login systems as attempts are not tracked correctly. Reconfigure settings.AXES_CACHE and settings.CACHES per django-axes configuration documentation.
?: (staticfiles.W004) The directory '/home/runner/work/posthog/posthog/frontend/dist' in the STATICFILES_DIRS setting does not exist.
BEGIN;
--
-- Add field default_pinned_properties to teamcustomeranalyticsconfig
--
ALTER TABLE "customer_analytics_teamcustomeranalyticsconfig" ADD COLUMN "default_pinned_properties" jsonb DEFAULT '[]'::jsonb NOT NULL;
ALTER TABLE "customer_analytics_teamcustomeranalyticsconfig" ALTER COLUMN "default_pinned_properties" DROP DEFAULT;
COMMIT;Last updated: 2026-09-29 18:48 UTC (fe319b8)
✅ Django migration risk — migration analysis complete
We've analyzed your migrations for potential risks.
Summary: 0 Safe | 1 Needs Review | 0 Blocked
⚠️ Needs Review
May have performance impact
customer_analytics.0060_teamcustomeranalyticsconfig_default_pinned_properties
└─ #1 ⚠️ AddField
Adding NOT NULL field with callable default (list) - verify it's stable
model: teamcustomeranalyticsconfig, field: default_pinned_properties, default: list
Last updated: 2026-09-29 18:49 UTC (fe319b8)
|
[High risk] Adds database schema field and API contract for account property configuration. The PR appears safe to merge based on the reviewed changes and resolved previous findings. Reviews (2) · Last reviewed commit: "fix(customer-analytics): keep pin kind e..." |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: PostHog/posthog/.coderabbit.yaml Review profile: QUIET Plan: Enterprise Run ID: 📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughAdds ordered project defaults for pinned account properties and user inheritance until a personal selection is saved. The team API validates references and stores the defaults. The account configuration interface lets admins edit defaults. Property-definition loading now reports failures, and relationship definitions load across pages. Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to Users inherit project defaults as intended, and the historical empty-list behavior is documented. No material merge risk remains. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Project defaults remain admin-controlled and project-scoped. The main risk is that some users who previously cleared their pins may see the new defaults until they clear them again. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✨ Finishing Touches 💡 1⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (3)
posthog/api/team.py-1142-1143 (1)
1142-1143: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winBind customer analytics validation before other config writes.
When a PATCH includes valid revenue or marketing settings and invalid default pins,
TeamSerializer.updatewrites the earlier settings before_update_customer_analytics_configraises a validation error. The project endpoint does not add an atomic wrapper, andATOMIC_REQUESTSis disabled. The API can therefore return HTTP 400 after persisting part of the request.Bind the nested serializer to the existing customer analytics config during outer validation:
🐛 Suggested fix
- @staticmethod - def validate_customer_analytics_config(value): + def validate_customer_analytics_config(self, value): if value is None: return None - serializer = TeamCustomerAnalyticsConfigSerializer(data=value) + instance = self.instance.customer_analytics_config if self.instance is not None else None + serializer = TeamCustomerAnalyticsConfigSerializer(instance=instance, data=value) if not serializer.is_valid(): raise exceptions.ValidationError(_format_serializer_errors(serializer.errors)) return serializer.validated_dataproducts/customer_analytics/backend/migrations/0060_inherit_default_pinned_properties.py-14-19 (1)
14-19: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winThe migration risk check is blocking this
RunSQLUPDATE.The
UPDATEscanscustomer_analytics_usercustomeranalyticsconfigand rewrites the matching rows in one transaction. This table has one row per user per project, so the row count grows with both. Take one of these actions to pass the check:
- Confirm that the table is small and record the size in a comment that the check accepts.
- Run the update in batches by primary key.
- Move the update to a background job.
Source: Pipeline failures
products/customer_analytics/backend/logic/user_customer_analytics_config.py-72-77 (1)
72-77: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winWrite customer analytics defaults to the canonical team row.
get_or_create_configcanonicalizes child team IDs, soread_pinned_propertiesreads the parent team's defaults.TeamSerializer._update_customer_analytics_configsavesinstance.customer_analytics_configdirectly. A PATCH for a child environment can therefore write the child row, while reads use the parent row. Resolve the canonical team before the write or before the default read.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 4a46d752-d5fa-401b-9528-63b9ecb821b8
⛔ Files ignored due to path filters (5)
frontend/src/generated/core/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.tsis excluded by!**/generated/**products/experiments/frontend/generated/api.schemas.tsis excluded by!**/generated/**services/mcp/src/generated/core/api.tsis excluded by!**/generated/**
📒 Files selected for processing (33)
docs/internal/customer-analytics/accounts-table.mdfrontend/src/queries/schema.jsonfrontend/src/queries/schema/schema-general.tsposthog/api/team.pyposthog/api/test/test_project.pyposthog/schema.pyposthog/schema_enums.pyproducts/customer_analytics/backend/facade/account_property_pins.pyproducts/customer_analytics/backend/facade/api.pyproducts/customer_analytics/backend/facade/contracts.pyproducts/customer_analytics/backend/facade/enums.pyproducts/customer_analytics/backend/logic/account_property_pins.pyproducts/customer_analytics/backend/logic/user_customer_analytics_config.pyproducts/customer_analytics/backend/migrations/0059_teamcustomeranalyticsconfig_default_pinned_properties.pyproducts/customer_analytics/backend/migrations/0060_inherit_default_pinned_properties.pyproducts/customer_analytics/backend/migrations/max_migration.txtproducts/customer_analytics/backend/models/team_customer_analytics_config.pyproducts/customer_analytics/backend/presentation/views/serializers.pyproducts/customer_analytics/backend/presentation/views/views.pyproducts/customer_analytics/backend/test/test_default_pinned_properties_migration.pyproducts/customer_analytics/backend/test/test_user_customer_analytics_config_api.pyproducts/customer_analytics/frontend/components/Accounts/AGENTS.mdproducts/customer_analytics/frontend/scenes/CustomerAnalyticsAccountScene/components/AccountPropertyConfigurator.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/CustomerAnalyticsAccountConfig.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/DefaultPinnedAccountProperties.stories.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/DefaultPinnedAccountProperties.test.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/DefaultPinnedAccountProperties.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/customPropertyDefinitionsLogic.tsproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/defaultPinnedAccountPropertiesLogic.test.tsproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/defaultPinnedAccountPropertiesLogic.tsproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/relationshipDefinitionsLogic.tsservices/mcp/src/api/generated.tsservices/mcp/tests/unit/__snapshots__/tool-schemas/project-settings-update.json
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.
eed080b to
c0f749f
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
posthog/api/test/test_project.py (1)
1156-1158: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSeed non-empty defaults before the permission check.
The stored list starts empty, so this assertion cannot detect an unauthorized clear that writes
[]before returning HTTP 403. Set a valid non-empty list before the member request, then assert that the same list remains afterward.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: f072b564-6129-433a-949e-f4b8d86f7eb2
⛔ Files ignored due to path filters (5)
frontend/src/generated/core/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.tsis excluded by!**/generated/**products/experiments/frontend/generated/api.schemas.tsis excluded by!**/generated/**services/mcp/src/generated/core/api.tsis excluded by!**/generated/**
📒 Files selected for processing (12)
docs/internal/customer-analytics/accounts-table.mdposthog/api/team.pyposthog/api/test/test_project.pyposthog/schema.pyproducts/customer_analytics/backend/logic/user_customer_analytics_config.pyproducts/customer_analytics/backend/migrations/max_migration.txtproducts/customer_analytics/backend/test/test_user_customer_analytics_config_api.pyproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/DefaultPinnedAccountProperties.stories.tsxproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/defaultPinnedAccountPropertiesLogic.tsproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/relationshipDefinitionsLogic.test.tsproducts/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/account/relationshipDefinitionsLogic.tsservices/mcp/src/api/generated.ts
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
c0f749f to
34332aa
Compare
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
…ount-properties Generated-By: PostHog Desktop Task-Id: 7d64331d-8aa6-437f-a268-595a35079e5c
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
products/customer_analytics/frontend/components/Accounts/AGENTS.md-166-166 (1)
166-166: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDocument inheritance for historical empty lists.
read_pinned_propertiesalso inherits project defaults whenproperties.pinned_propertiesis an empty list, the override marker is not true, and no legacy pinned IDs exist. Add this case to the guide so readers do not treat every stored empty list as a personal override. As per coding guidelines, “Whenever you change the Accounts area … update this file in the same change so it stays an accurate map.”Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: 03d6718d-bde0-4b81-9f1a-fc457801113b
⛔ Files ignored due to path filters (5)
frontend/src/generated/core/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/customer_analytics/frontend/generated/api.tsis excluded by!**/generated/**products/experiments/frontend/generated/api.schemas.tsis excluded by!**/generated/**services/mcp/src/generated/core/api.tsis excluded by!**/generated/**
📒 Files selected for processing (4)
products/customer_analytics/backend/facade/api.pyproducts/customer_analytics/backend/presentation/views/serializers.pyproducts/customer_analytics/frontend/components/Accounts/AGENTS.mdservices/mcp/src/api/generated.ts
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 7 remain after this review.
|
🕓 This approval covered an earlier revision. There are new visual changes to review in the newer comment below. ✅ Visual changes approved by @arthurdedeus — baseline updated in 2 new. Install the Visual Review Chrome extension to see visual review results at the top of your pull requests. |
2 updated Run: 71f6e950-6763-448f-97d7-b812383b4daa Co-authored-by: arthurdedeus <54866778+arthurdedeus@users.noreply.github.com>
# Conflicts: # products/customer_analytics/backend/facade/enums.py # products/customer_analytics/backend/migrations/max_migration.txt
|
✅ Visual changes approved by @arthurdedeus — baseline updated in 1 changed, 2 new. Changed
New
Install the Visual Review Chrome extension to see visual review results at the top of your pull requests. |
3 updated Run: 0c6c426a-8106-49a8-bc4b-9a659de9beef Co-authored-by: arthurdedeus <54866778+arthurdedeus@users.noreply.github.com>
There was a problem hiding this comment.
Not approved yet — waiting on the conditions below.
Re-add the stamphog label to request another review once you have addressed this.
stamphog won't auto-review this pull request because three gates refused it. The deny-list gate matched a migration (products/customer_analytics/backend/migrations/0060_teamcustomeranalyticsconfig_default_pinned_properties.py). The size gate found 864 substantive lines against an 800-line ceiling, and the tier gate classified the change as T2-never (cross-cutting feature, 39 files, 1404 lines including docs, generated files and snapshots).
Please ask a human reviewer to look at it. To make it smaller, you could split the work into separate pull requests, for example the migration and backend API first and the settings UI afterward. Even with a split, any part that includes the migration would still need human review.
- 👍 on the PR from greptile-apps[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✗ | matches: migrations |
| size | ✗ | too large for auto-review (864L substantive in global — ceiling is 800L; 864L, 23F total, 1404L/39F incl. docs/generated/snapshots) |
| tier | ✗ | classified as T2-never: T2-never (1404L, 39F, cross-cutting, feat) |
| stamphog 2.3.1 | .stamphog/policy.yml @ unknown · reviewed head fe319b8 |
Problem
Project admins cannot choose the account properties people see before saving a personal sidebar selection.
Every user starts with an empty account sidebar and must configure the same useful properties independently.
Changes
Warning
Existing data cannot distinguish an auto-created empty selection from an intentional clear. Those users may need to clear the defaults once again.
Before this change, Accounts settings had no default-pins control. The configured state now shows the ordered project defaults:
How did you test this code?
pnpm --filter=@posthog/frontend typescript:checkuv run mypy --cache-fine-grained .hogli product:lint customer_analyticshogli ci:preflight --strictThe PR assignee manually verified the complete inheritance flow:
👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Release status
Automatic notifications
Docs update
Updated the Customer analytics Accounts table guide and generated API descriptions. The Inkeep docs agent can assess published documentation changes.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: pi,
gpt-5.6-sol(initial code) andgpt-6-sol(follow-up fixes)/django-migrations,/improving-drf-endpoints,/implementing-mcp-tools,/writing-tests,/writing-ui-components,/writing-user-facing-copy,/writing-kea-logics,/editing-agents-md,/running-ci-preflight,/debugging-ci-failures,/announcing-behavior-changes,/orwell-writing,/write-snapshot-test,/setting-feature-flags-in-storybook,/writing-pr-descriptions, and/ship-it.