Agent skill · posthog

adding-activity-logging

Adds or changes activity logging (the audit trail) for a Django model in PostHog. Use when a model's writes must show in the Activity side panel or the advanced activity logs, when adding ModelActivityMixin, an ActivityScope, a model_activity_signal receiver, an activity describer, or field exclusions, when auditing which write paths of a model are logged, or when a change is missing from the activity log. Covers the receiver-module convention, writes the signal cannot see (QuerySet.update, bulk_create), the actor outside requests, and product models on a separate database. Trigger terms - activity log, audit log, audit trail, ModelActivityMixin, log_activity, changes_between, activity describer, who changed this.

What it needs

About 3k tokens when loaded.

What this skill does

Adding activity logging Read docs/internal/activity-logging.md first. It carries the pipeline, the file locations, and the reasons. This skill carries the workflow and the gates. Reference implementation: products/featureflags/backend/activitylogging.py with its apps.py. Separate-database reference: products/stamphog/backend/activitylogging.py. Step 1 - Find every write path before you touch the model The mixin hooks save() and delete(). It does not see QuerySet.update(), bulkcreate(), bulkupdate(), or raw SQL. A receiver that logs only the API path gives an audit trail that says nobody changed a row a webhook changed. Write the list down: which paths call save() (the mixin covers them) and which do bulk writes (you log those by hand in step 5). Include tasks, Temporal activities, webhook handlers, and management commands. Step 2 - Model and scope Add ModelActivityMixin first in the bases: class Thing(ModelActivityMixin, TeamScopedRootMixin, ...). Set activityloggingondelete = True only when a hard delete must show in the log. Add the class name to ActivityScope in posthog/models/activitylogging/activitylog.py. Add the same string to the ActivityScope enum in frontend/src/types.ts. Run hogli build:openapi (needs the dev stack) because the API scope filter enum is generated from the Literal. No migration is needed. The mixin adds no field. Step 3 - Receiver module Create products/<name>/backend/activitylogging.py. One @mutablereceiver(modelactivitysignal, sender=Thing) per model. The receiver calls changesbetween and logactivity; nothing else. Keep the module import-light. It must not import a viewset, a serializer, or a query runner. ready() imports it at django.setup() in every process. For a model without a .team foreign key (ProductTeamModel), read organizationid from Team on the main database inside the receiver. …

How to use it

Reference it in AdaL, Claude Code, Cursor or any coding agent — nothing to install:

@skills posthog/adding-activity-logging

View the source on GitHub

Browse the @skills marketplace