feat(web-analytics): list, refresh and dismiss content opportunities - #108593
jordanm-posthog wants to merge 4 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🤖 CI report
|
| First copy | Second copy | Lines | Tokens |
|---|---|---|---|
posthog/temporal/experiments/workflows.py:187 |
posthog/temporal/experiments/workflows.py:282 |
45 | 208 |
posthog/temporal/ai_observability/run_aggregate_evaluation.py:692 |
posthog/temporal/ai_observability/run_trace_evaluation.py:928 |
38 | 203 |
products/warehouse_sources/backend/temporal/data_imports/tests/e2e/test_import_data.py:133 |
products/warehouse_sources/backend/temporal/data_imports/tests/e2e/test_import_data.py:259 |
50 | 189 |
products/warehouse_sources/backend/temporal/data_imports/sources/fly_io/tests/test_fly_io.py:25 |
products/warehouse_sources/backend/temporal/data_imports/sources/moxie/tests/test_moxie.py:28 |
21 | 179 |
products/warehouse_sources/backend/tests/management/test_backfill_warehouse_queue_state.py:40 |
products/warehouse_sources_queue/backend/core/jobs_db.py:945 |
13 | 175 |
products/warehouse_sources/backend/temporal/data_imports/sources/companycam/source.py:1 |
products/warehouse_sources/backend/temporal/data_imports/sources/motion/source.py:1 |
21 | 164 |
products/warehouse_sources/backend/temporal/data_imports/sources/companycam/source.py:1 |
products/warehouse_sources/backend/temporal/data_imports/sources/wix/source.py:1 |
21 | 164 |
products/warehouse_sources/backend/temporal/data_imports/sources/companycam/source.py:1 |
products/warehouse_sources/backend/temporal/data_imports/sources/expo/source.py:1 |
21 | 162 |
products/warehouse_sources/backend/temporal/data_imports/tests/e2e/test_import_data.py:144 |
products/warehouse_sources/backend/temporal/data_imports/tests/e2e/test_import_data.py:354 |
38 | 156 |
products/warehouse_sources/backend/temporal/data_imports/sources/descope/descope.py:4 |
products/warehouse_sources/backend/temporal/data_imports/sources/motion/motion.py:1 |
20 | 145 |
products/warehouse_sources/backend/temporal/data_imports/sources/adroll/source.py:15 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/source.py:17 |
16 | 144 |
products/warehouse_sources/backend/temporal/data_imports/sources/front/front.py:3 |
products/warehouse_sources/backend/temporal/data_imports/sources/spot_io/spot_io.py:3 |
20 | 141 |
products/workflows/backend/presentation/views/hog_flow.py:5339 |
products/workflows/backend/presentation/views/hog_flow.py:5438 |
25 | 139 |
posthog/temporal/ai_observability/run_aggregate_evaluation.py:584 |
posthog/temporal/ai_observability/run_trace_evaluation.py:855 |
24 | 135 |
products/warehouse_sources/backend/temporal/data_imports/sources/convertkit/convertkit.py:1 |
products/warehouse_sources/backend/temporal/data_imports/sources/fulcrum/fulcrum.py:2 |
18 | 134 |
products/signals/backend/scout_harness/tools/report.py:1475 |
products/signals/backend/scout_harness/tools/report.py:1647 |
21 | 133 |
products/mcp_analytics/backend/hogql_queries/model_breakdown.py:48 |
products/mcp_analytics/backend/hogql_queries/protocol_version_breakdown.py:50 |
14 | 121 |
products/signals/backend/scout_harness/tools/report.py:1604 |
products/signals/backend/scout_harness/tools/report.py:1754 |
30 | 118 |
posthog/temporal/ai_observability/run_session_evaluation.py:466 |
posthog/temporal/ai_observability/run_trace_evaluation.py:664 |
24 | 115 |
products/warehouse_sources/backend/temporal/data_imports/sources/dovetail/dovetail.py:4 |
products/warehouse_sources/backend/temporal/data_imports/sources/front/front.py:4 |
17 | 114 |
products/batch_exports/backend/api/batch_export.py:2092 |
products/batch_exports/backend/api/batch_export.py:2131 |
24 | 112 |
products/warehouse_sources_queue/backend/core/jobs_db.py:203 |
products/warehouse_sources_queue/backend/core/jobs_db.py:264 |
11 | 112 |
products/workflows/backend/management/commands/backfill_hogflow_billable_action_types.py:49 |
products/workflows/backend/management/commands/refresh_hog_flows.py:69 |
23 | 112 |
products/warehouse_sources/backend/temporal/data_imports/sources/capsule_crm/capsule_crm.py:138 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:119 |
23 | 105 |
products/warehouse_sources/backend/temporal/data_imports/sources/aha/aha.py:227 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:164 |
15 | 104 |
products/warehouse_sources/backend/temporal/data_imports/sources/aha/aha.py:227 |
products/warehouse_sources/backend/temporal/data_imports/sources/fulcrum/fulcrum.py:182 |
15 | 104 |
products/workflows/backend/presentation/views/hog_flow.py:7080 |
products/workflows/backend/presentation/views/hog_flow.py:7124 |
16 | 104 |
products/warehouse_sources/backend/temporal/data_imports/sources/ashby/ashby.py:12 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/cloudinary.py:5 |
12 | 102 |
products/warehouse_sources/backend/temporal/data_imports/sources/common/byte_bounded_extraction_flag.py:47 |
products/warehouse_sources/backend/temporal/data_imports/sources/common/keyset_full_load_flag.py:50 |
15 | 99 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshcaller/freshcaller.py:187 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshdesk/freshdesk.py:282 |
18 | 98 |
products/warehouse_sources/backend/temporal/data_imports/sources/aha/aha.py:229 |
products/warehouse_sources/backend/temporal/data_imports/sources/front/front.py:182 |
13 | 97 |
products/warehouse_sources/backend/temporal/data_imports/sources/pardot/pardot.py:2 |
products/warehouse_sources/backend/temporal/data_imports/sources/wix/wix.py:1 |
12 | 97 |
products/mcp_analytics/backend/hogql_queries/dashboard_series.py:16 |
products/mcp_analytics/backend/hogql_queries/protocol_version_breakdown.py:8 |
20 | 96 |
products/warehouse_sources/backend/temporal/data_imports/sources/brex/brex.py:20 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshdesk/freshdesk.py:19 |
25 | 96 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/cloudinary.py:64 |
products/warehouse_sources/backend/temporal/data_imports/sources/motion/motion.py:57 |
15 | 96 |
products/warehouse_sources/backend/temporal/data_imports/sources/flexmail/flexmail.py:28 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:5 |
13 | 96 |
products/warehouse_sources/backend/temporal/data_imports/sources/bamboohr/bamboohr.py:35 |
products/warehouse_sources/backend/temporal/data_imports/sources/fulcrum/fulcrum.py:18 |
21 | 92 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudability/cloudability.py:13 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/cloudinary.py:5 |
11 | 92 |
products/workflows/backend/presentation/views/message_assets.py:243 |
products/workflows/backend/presentation/views/message_assets.py:296 |
19 | 90 |
products/warehouse_sources/backend/temporal/data_imports/sources/adroll/adroll.py:14 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:18 |
19 | 89 |
products/warehouse_sources/backend/temporal/data_imports/sources/canvas_lms/canvas_lms.py:21 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:10 |
11 | 88 |
products/warehouse_sources/backend/temporal/data_imports/sources/blogger/blogger.py:19 |
products/warehouse_sources/backend/temporal/data_imports/sources/float_app/float_app.py:15 |
12 | 87 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/cloudinary.py:66 |
products/warehouse_sources/backend/temporal/data_imports/sources/loops/loops.py:86 |
13 | 87 |
products/warehouse_sources/backend/temporal/data_imports/sources/bugherd/bugherd.py:16 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshchat/freshchat.py:7 |
11 | 86 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshservice/freshservice.py:2 |
products/warehouse_sources/backend/temporal/data_imports/sources/opn_payments/opn_payments.py:1 |
13 | 86 |
products/workflows/backend/presentation/views/message_assets.py:118 |
products/workflows/backend/presentation/views/message_assets.py:154 |
23 | 85 |
products/warehouse_sources/backend/temporal/data_imports/sources/assemblyai/assemblyai.py:134 |
products/warehouse_sources/backend/temporal/data_imports/sources/front/front.py:247 |
15 | 82 |
products/workflows/backend/presentation/views/hog_flow.py:6308 |
products/workflows/backend/presentation/views/hog_flow.py:6346 |
12 | 80 |
products/warehouse_sources/backend/temporal/data_imports/sources/bluesky/bluesky.py:97 |
products/warehouse_sources/backend/temporal/data_imports/sources/cloudinary/cloudinary.py:67 |
14 | 79 |
posthog/api/llm_prompt.py:120 |
products/skills/backend/api/skills.py:591 |
13 | 78 |
products/warehouse_sources/backend/temporal/data_imports/sources/clickup/clickup.py:249 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshchat/freshchat.py:285 |
11 | 78 |
products/warehouse_sources/backend/temporal/data_imports/sources/faire/faire.py:1 |
products/warehouse_sources/backend/temporal/data_imports/sources/float_app/float_app.py:3 |
12 | 78 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshdesk/source.py:108 |
products/warehouse_sources/backend/temporal/data_imports/sources/shipmail/source.py:82 |
16 | 77 |
products/warehouse_sources/backend/temporal/data_imports/external_product_hooks.py:270 |
products/warehouse_sources/backend/temporal/data_imports/external_product_hooks.py:312 |
11 | 76 |
products/warehouse_sources/backend/temporal/data_imports/sources/aircall/aircall.py:341 |
products/warehouse_sources/backend/temporal/data_imports/sources/freshdesk/freshdesk.py:239 |
11 | 75 |
products/warehouse_sources/backend/temporal/data_imports/pipelines/pipeline_v3/postgres_queue/test_consumer.py:99 |
products/warehouse_sources_queue/backend/testing.py:128 |
18 | 73 |
products/mcp_analytics/backend/hogql_queries/model_breakdown.py:13 |
products/mcp_analytics/backend/hogql_queries/protocol_version_breakdown.py:13 |
18 | 72 |
products/workflows/backend/presentation/views/workflow_scout_runs.py:54 |
products/workflows/backend/presentation/views/workflow_tasks.py:41 |
12 | 72 |
products/signals/backend/scout_harness/tools/report.py:1516 |
products/signals/backend/scout_harness/tools/report.py:1675 |
12 | 71 |
products/signals/backend/scout_harness/tools/report.py:1531 |
products/signals/backend/scout_harness/tools/report.py:1690 |
16 | 70 |
products/workflows/backend/presentation/views/hog_flow.py:7080 |
products/workflows/backend/presentation/views/hog_flow.py:7171 |
11 | 70 |
⚠️ Duplication (TypeScript) — 36 new duplicated blocks (worst 498 tokens)
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.
| First copy | Second copy | Lines | Tokens |
|---|---|---|---|
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:981 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1738 |
247 | 498 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:381 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:546 |
134 | 293 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1106 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1603 |
140 | 284 |
frontend/src/layout/scenes/ConfigureHomeModalContent.tsx:89 |
frontend/src/layout/scenes/HomepageConfiguration.tsx:99 |
67 | 282 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:209 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:180 |
128 | 264 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:210 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:693 |
126 | 257 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1104 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1352 |
127 | 257 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:721 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:848 |
124 | 248 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:22 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1230 |
123 | 248 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:417 |
123 | 247 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/accessControlLogic.ts:666 |
123 | 247 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:982 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1480 |
123 | 247 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:389 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:982 |
122 | 246 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:158 |
123 | 246 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:1106 |
123 | 246 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/accessControlLogic.ts:314 |
123 | 246 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:22 |
122 | 245 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:59 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:281 |
122 | 245 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:389 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:820 |
121 | 244 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:739 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/accessControlLogic.ts:542 |
122 | 244 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:214 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:60 |
122 | 243 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:214 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:461 |
122 | 243 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:214 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:590 |
122 | 243 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:214 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:740 |
122 | 243 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:214 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:331 |
121 | 242 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:389 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:722 |
121 | 241 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:390 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:568 |
120 | 240 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:390 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:215 |
120 | 240 |
products/business_knowledge/frontend/scenes/settings/businessKnowledgeSettingsLogic.test.ts:10 |
products/data_catalog/frontend/certificationsLogic.test.ts:17 |
23 | 158 |
products/business_knowledge/frontend/scenes/settings/businessKnowledgeSettingsLogic.test.ts:10 |
products/data_quality/frontend/dataQualityGateLogic.test.ts:14 |
23 | 158 |
frontend/src/layout/scenes/ConfigureHomeModalContent.tsx:1 |
frontend/src/layout/scenes/HomepageConfiguration.tsx:1 |
37 | 139 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessControlsLogic.ts:476 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/groupedAccessControlRuleModalLogic.ts:641 |
40 | 80 |
frontend/src/layout/panel-layout/navbar/tabs/navProductsTabLogic.ts:139 |
products/workflows/frontend/TemplateLibrary/newTemplateAgentLogic.ts:64 |
22 | 76 |
frontend/src/layout/panel-layout/navbar/tabs/navProductsTabLogic.ts:140 |
frontend/src/lib/memory/autofillReleaseLogic.ts:10 |
21 | 75 |
products/ai_observability/frontend/components/GenerationEvalRunsTable.tsx:21 |
products/ai_observability/frontend/evaluations/components/EvaluationRunsTable.tsx:97 |
11 | 74 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/accessDetailLogic.ts:300 |
frontend/src/layout/navigation-3000/sidepanel/panels/access_control/ResourceAccessControlsV2/addObjectOverrideModalLogic.ts:271 |
38 | 73 |
⚠️ Bundle size — 🔺 +89.8 KiB (+0.1%)
Uncompressed size of every built .js bundle, compared against the base branch.
Total: 68.97 MiB · 🔺 +89.8 KiB (+0.1%)
| File | Size | Δ vs base |
|---|---|---|
posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgePlaygroundScene.js |
removed | 🟢 -26.2 KiB (-100.0%) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/playground/BusinessKnowledgePlaygroundScene.js |
26.1 KiB | 🔺 +26.1 KiB (new) |
render-query/src/render-query/render-query.js |
20.18 MiB | 🔺 +19.9 KiB (+0.1%) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene.js |
removed | 🟢 -18.7 KiB (-100.0%) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/sources/BusinessKnowledgeScene.js |
18.6 KiB | 🔺 +18.6 KiB (new) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/KnowledgeSourceScene.js |
removed | 🟢 -18.0 KiB (-100.0%) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/source/KnowledgeSourceScene.js |
18.0 KiB | 🔺 +18.0 KiB (new) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeSettingsScene.js |
removed | 🟢 -16.8 KiB (-100.0%) |
posthog-app/_parent/products/business_knowledge/frontend/scenes/settings/BusinessKnowledgeSettingsScene.js |
16.8 KiB | 🔺 +16.8 KiB (new) |
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js |
491.0 KiB | 🔺 +16.1 KiB (+3.4%) |
posthog-app/_parent/products/data_modeling/frontend/nodeDetail/NodeDetailScene.js |
33.3 KiB | 🔺 +8.0 KiB (+31.6%) |
exporter/src/queries/schema.js |
1.23 MiB | 🔺 +7.6 KiB (+0.6%) |
posthog-app/src/queries/schema.js |
1.23 MiB | 🔺 +7.6 KiB (+0.6%) |
posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation.js |
87.0 KiB | 🔺 +5.9 KiB (+7.3%) |
posthog-app/src/scenes/AuthenticatedShell.js |
254.1 KiB | 🔺 +5.7 KiB (+2.3%) |
posthog-app/src/scenes/notebooks/NotebookScene.js |
37.0 KiB | 🔺 +5.6 KiB (+17.8%) |
posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene.js |
185.5 KiB | 🔺 +4.5 KiB (+2.5%) |
posthog-app/_parent/products/workflows/frontend/Broadcasts/BroadcastScene.js |
67.3 KiB | 🔺 +3.7 KiB (+5.9%) |
posthog-app/_parent/products/stamphog/frontend/scenes/StamphogDigestsScene/StamphogDigestsScene.js |
9.5 KiB | 🔺 +1.6 KiB (+20.7%) |
posthog-app/_parent/products/stamphog/frontend/scenes/StamphogScene/StamphogScene.js |
22.1 KiB | 🔺 +1.1 KiB (+5.4%) |
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 | 🔺 +330 B (+0.0%) | █████████░ 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 | 🔺 +3.0 KiB (+0.1%) | █████████░ 87.4% of 4.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.35 MiB · 2,339 files | 🔺 +13.2 KiB (+0.2%) | █████████░ 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 | 🔺 +478 B (+0.0%) | ████░░░░░░ 37.8% of 5.72 MiB |
| Deferred (lazy) | 2.10 MiB · 44 files | 🔺 +588 B (+0.0%) | 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 — 🔺 +1.38 MiB (+0.1%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 947.83 MiB · 🔺 +1.38 MiB (+0.1%)
ℹ️ 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 |
|
[Medium risk] Adds listing, refresh, and dismiss operations for content opportunities. The PR does not appear safe to merge while dismissed opportunities remain visible in list responses. Reviews (2) · Last reviewed commit: "fix(web-analytics): describe what dismis..." |
| queryset = ContentAutopilotOpportunity.objects.for_team(self.team_id).filter(profile__deleted=False) | ||
| if self.action == "list": | ||
| filters = self.validated_query_params(ContentAutopilotOpportunityListQuerySerializer) | ||
| queryset = queryset.filter(profile_id=filters["profile_id"]) | ||
| return queryset.order_by("-score", "title") |
There was a problem hiding this comment.
Dismissed opportunities remain visible
After a user dismisses an opportunity, this list query still returns it because it does not filter out dismissed rows. The refresh response also returns dismissed rows, so dismissal does not hide the opportunity as the API promises. Exclude dismissed opportunities from both responses and test a list request made after dismissal.
Prompt To Fix With AI
This is a comment left during a code review.
Path: products/web_analytics/backend/presentation/views/content_autopilot.py
Line: 654-658
Comment:
**Dismissed opportunities remain visible**
After a user dismisses an opportunity, this list query still returns it because it does not filter out dismissed rows. The refresh response also returns dismissed rows, so dismissal does not hide the opportunity as the API promises. Exclude dismissed opportunities from both responses and test a list request made after dismissal.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 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 ignored due to path filters (1)
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review. 📝 WalkthroughWalkthroughThe change adds team-scoped opportunity listing, refresh, and dismissal endpoints. It adds serializers and generated API types for opportunities, engine answers, and citation-gap data. The route and disabled MCP tools expose the operations. Tests cover profile filtering, dismissal, and team scoping. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The opportunity API is gated and team-scoped, and dismissed opportunities intentionally remain visible with their status. No identified issue blocks merging. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The new endpoints broaden access to opportunity data and refresh controls, but the reviewed paths preserve team scoping, a feature flag, and write authorization for mutations. No material security boundary violation was established. 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📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: f565f843-7eb1-4e14-bf93-c785c5c33bae
⛔ Files ignored due to path filters (3)
products/web_analytics/frontend/generated/api.schemas.tsis excluded by!**/generated/**products/web_analytics/frontend/generated/api.tsis excluded by!**/generated/**products/web_analytics/frontend/generated/api.zod.tsis excluded by!**/generated/**
📒 Files selected for processing (8)
posthog/test/repo_invariants/test_pagination_contract.pyproducts/web_analytics/backend/facade/content_autopilot.pyproducts/web_analytics/backend/presentation/views/content_autopilot.pyproducts/web_analytics/backend/routes.pyproducts/web_analytics/backend/test/test_content_autopilot_api.pyproducts/web_analytics/backend/test/test_content_autopilot_lifecycle.pyproducts/web_analytics/mcp/tools.yamlservices/mcp/src/api/generated.ts
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 9 remain after this review.
| queryset = ContentAutopilotOpportunity.objects.for_team(self.team_id).filter(profile__deleted=False) | ||
| if self.action == "list": | ||
| filters = self.validated_query_params(ContentAutopilotOpportunityListQuerySerializer) | ||
| queryset = queryset.filter(profile_id=filters["profile_id"]) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Exclude dismissed opportunities from both list responses.
After dismiss_opportunity sets an opportunity’s status to DISMISSED, both the list query and the refresh query still return it. The dismiss action says it hides the opportunity from the list. Filter DISMISSED rows from both queries while keeping detail lookup available for the dismissal response. (raw.githubusercontent.com)
Also applies to: 674-674
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🦔 Hogbox preview · 🔧 building…Spinning up PostHog for this PR on a hogland hogbox — this comment updates in place when it's ready (usually a few minutes). commit |
Problem
Content autopilot can rank questions that AI assistants answer without citing the site (#108121), but nothing outside the backend can read that list yet. The workspace UI in a later PR needs an API to list, refresh and dismiss those opportunities.
Part 4 of the content autopilot stack, stacked on #108121, behind the
web-analytics-content-autopilotflag.Changes
web_analytics_content_autopilot_opportunities, lists a site's opportunities, highest priority first.profile_idis required.refreshre-reads the AEO citation checks for one site and returns the updated list. It makes no model calls.dismisshides one opportunity. It returns 404 for another team's opportunity, and refuses one that a run is drafting.brief,source_ledgerandresearchcolumns.listis the standard DRF one, wrapped byextend_schema_viewto documentprofile_id.How did you test this code?
profile_id, listing per site, the typed gap payload and dismissal.👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Release status
Automatic notifications
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (1M context)
/improving-drf-endpoints,/stacking-prs,/reviewing-with-coderabbit,/writing-pr-descriptions.--deepagainst the feat(web-analytics): score content opportunities from citation gaps #108121 branch, with 0 findings.example.comdomains and invented data.🤖 Generated with Claude Code