feat(subscriptions): add AI-prompt subscription fields + activity logging#59629
feat(subscriptions): add AI-prompt subscription fields + activity logging#59629vdekrijger wants to merge 2 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: 0 Safe | 0 Needs Review | 1 Blocked ❌ BlockedCauses locks or breaks compatibility 📚 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. RunPython: Use batching for large data migrations:
See the migration safety guide Last updated: 2026-05-26 13:50 UTC (f4952a3) |
| if not created and is_scheduler_save: | ||
| return | ||
| try: | ||
| from posthog.models.activity_logging.activity_log import Detail, log_activity |
There was a problem hiding this comment.
If we decide to do this activity log thing, we should at least move this to a global import instead of a local one.
There was a problem hiding this comment.
Done — activity logging now lives in a top-level @mutable_receiver(model_activity_signal) handler, so log_activity / Detail / changes_between are imported at module level (no inline import).
| detail=Detail( | ||
| name=instance.title or (instance.prompt or "")[:60], | ||
| short_id=None, | ||
| changes=None, |
There was a problem hiding this comment.
Honestly, given that you claim that the AI subscriptions carry value to log activities (which I think is fair in order to allow undos to prompts and what not), I think we should track the changes to the prompt / model in the details here as well so that we can track what changed and undo / redo them?
There was a problem hiding this comment.
Done — switching to ModelActivityMixin means changes_between auto-computes the field diff (before/after for prompt, etc.) into Detail.changes, so prompt edits are recoverable from the audit trail. Added tests covering create, prompt edits, and None↔prompt transitions. (target_value stays masked via the existing config.)
| organization_id=instance.team.organization_id, | ||
| team_id=instance.team_id, | ||
| user=instance.created_by, | ||
| was_impersonated=False, |
There was a problem hiding this comment.
How do we do this in other placeS? Shouldn't this be some function call?
There was a problem hiding this comment.
Good call — it now follows the standard pattern: Subscription inherits ModelActivityMixin and a @mutable_receiver(model_activity_signal, sender=Subscription) handler logs the activity, mirroring AlertConfiguration. Scheduler-only saves (next_delivery_date) are suppressed via signal_exclusions so a schedule bump isn't logged.
| SubscriptionFrequency.YEARLY: YEARLY, | ||
| } | ||
|
|
||
| content_type = models.CharField( |
There was a problem hiding this comment.
In this PR, we don't set the content type in the API / during sub creation, which means that there will be a gap in the column until the frontend has caught up; can we consider adding a backend thing here so that there is no gap between the migration and the frontend? and that we can consider all subs having a content type?
- 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)

Problem
Changes
How did you test this code?
👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Publish to changelog?
Docs update
🤖 Agent context