feat(subscriptions): add AI-prompt subscription fields + activity logging#59629
feat(subscriptions): add AI-prompt subscription fields + activity logging#59629vdekrijger wants to merge 6 commits into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
🎭 Playwright didn't run on this PR — your changes touch code that could affect E2E behavior, but Playwright is opt-in via label now to keep CI cost down. Add the Most PRs don't need this. Real regressions still get caught on master and fix-forward. |
Migration SQL ChangesHey 👋, we've detected some migrations on this PR. Here's the SQL output for each migration, make sure they make sense:
|
🔍 Migration Risk AnalysisWe've analyzed your migrations for potential risks. Summary: 1 Safe | 0 Needs Review | 0 Blocked ✅ SafeBrief or no lock, backwards compatible 📚 How to Deploy These Changes SafelyAddField: This operation acquires a brief lock but doesn't rewrite the table. Deployment uses lock timeouts with automatic retries, so lock contention will cause retries rather than connection pile-up. Last updated: 2026-05-27 11:34 UTC (429d4c6) |
- rename content_type -> resource_type (avoids clash with django contenttypes)
- drop ai_config (YAGNI; not part of MVP)
- move activity logging onto ModelActivityMixin + a model_activity_signal
receiver (matches AlertConfiguration), so changes are auto-diffed for the
audit trail and the activity_log import is module-level
- exclude next_delivery_date from both the signal and the change diff so
scheduler bumps are not logged
- fix AI resource kind ("AI" not "AI report") so email subjects read correctly
- extract ai_display_name + AI_PROMPT_DISPLAY_MAX_LEN to remove duplication
- add activity-logging tests (create/update/scheduler/soft-delete/transitions)
Address review feedback on PR #59629: - Log activity for all subscription changes, not just AI (records are cheap and useful for debugging/undo); drop the AI_PROMPT and created_by guards - Generalise ai_display_name into a display_name property that resolves the name for insight/dashboard/AI subscriptions via resource_info - Remove redundant inline comments flagged in review Infra was already in place (Subscription is a registered activity scope, next_delivery_date excluded from both signal and diff, target_value masked).
…aren't misclassified
…n resource_type tests
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
posthog/models/test/test_subscription_activity_log.py:37-82
**AI and non-AI creation tests can be unified**
`test_creating_ai_subscription_logs_activity` and `test_non_ai_subscription_logs_activity` test the same assertion pattern (count, activity, item_id, name) for three symmetric cases. The AI case can be added as a third entry in the `@parameterized.expand` list so all three resource-type creation scenarios live in one parameterised test, following the team's preference for parameterised tests over one-off test methods for symmetric cases.
Reviews (1): Last reviewed commit: "chore(subscriptions): drop explanatory c..." | Re-trigger Greptile |
ClickHouse migration SQL per cloud environmentNo ClickHouse migrations changed in this PR. |

Problem
Subscriptions currently only support insights and dashboards as their target resource. To support AI-powered subscription reports (where a user provides a prompt rather than linking to an existing insight or dashboard), the model needs a way to represent and classify this new resource type.
Additionally, subscription saves were not being recorded in the activity log, making it impossible to audit changes to subscription configuration.
Changes
promptfield toSubscriptionfor AI-prompt subscriptionsinsight,dashboard, orai_promptvia a derivedresource_typeproperty rather than a stored column. Because it is computed on read from the existing relation/prompt:resource_typenever shows up as its own spurious changeResourceTypechoices are retained for the resource-type lookups needed by the follow-up PRsurlandresource_infonow dispatch on the derivedresource_typedisplay_nameproperty that resolves a human-readable name from the subscription's resource info, falling back gracefully through title → prompt snippet → "AI report"Subscriptioninto the activity logging system viaModelActivityMixinand amodel_activity_signalreceiver, so creates and updates are recorded in the activity lognext_delivery_datefrom both signal emission (viasignal_exclusions) and change diffs (viadiff_exclusions), so scheduler-only saves never produce spurious activity log entriesresource_type(derived) andprompt_lengthtoget_analytics_metadata()SUBSCRIPTION_AI_PROMPT_FEATURE_FLAG_KEY = "ai-subscriptions"How did you test this code?
New test file
test_subscription_activity_log.pycovers:display_nameresolution across all resource types and fallback casesnext_delivery_datefrom diffs even in mixed savesupdate_fields) producing no new log entriesExisting
test_subscription_model.pyextended with parameterized tests verifyingresource_typeis correctly derived from the relation.Publish to changelog?
No