Models that belong to an organization via a parent model (for example
project members via their project) implement AuditableThroughParent and
return the parent relation. The owner organization of their audits is
taken from the loaded parent if it matches the foreign key, otherwise it
is queried. The declaration is also used to backfill the owner of
existing audits.
Models implementing AuditableWithoutOwner intentionally have no audit
owner, either because they belong to neither an organization nor a user,
or because they and their audits have to be kept when the owner is
deleted (for example billing records). Adds helpers and a scope on the
audit model to find audits that are missing an owner although they
should have one.
- Rename the audit actor columns user_type/user_id to actor_type/actor_id
- Add owner_organization_id and owner_user_id to the audits table as
foreign keys with cascade on delete, so that the audits of an
organization or user are deleted together with it. The indexes and
foreign keys are created without blocking writes on the large table.
- Fill the owner columns for new audits via CustomAuditable. Organizations
and users no longer record their own deletion audit, since it would
reference the already deleted owner.