Skip to content

Models

The core.models module provides foundational abstract models and system-level entities used across the backend.

These models define shared structure for:

  • timestamps
  • organization scoping
  • audit ownership
  • system-wide audit logging

Overview

The core models fall into two categories:

Abstract base models

Reusable building blocks for other apps: - TimeStampedModel - OrgScopedModel - AuditModel

Concrete system model

  • AuditLog (used globally for audit tracking)

Abstract Models

TimeStampedModel

Provides automatic timestamp tracking.

Fields: - created_at → set on object creation - updated_at → updated on every save


Purpose

Used as a base for most domain models to ensure:

  • consistent tracking of creation time
  • consistent tracking of last modification

OrgScopedModel

Extends TimeStampedModel and enforces organization ownership.

Fields: - org → ForeignKey to Organization


Purpose

Ensures that:

  • every business object belongs to exactly one organization
  • multi-tenant isolation is enforced at the data level

Behavior

  • uses PROTECT on delete to avoid accidental cascading
  • provides dynamic related_name for reverse lookups

AuditModel

Adds user tracking for object ownership.

Fields: - created_by → user who created the object - updated_by → user who last modified the object


Purpose

Used for:

  • accountability
  • traceability
  • auditability at the model level

Concrete Models

AuditLog

The central system-wide audit log model.

This model records:

  • who performed an action
  • what action was performed
  • what object was affected
  • what changed

Fields

actor

  • ForeignKey to User
  • nullable (system actions allowed)

Represents the user who triggered the action.


action

  • string identifier (max 64 chars)

Examples: - team.created - team.updated - org_membership.deactivated


object_repr

  • string representation of the object (snapshot)
  • used for legacy compatibility and quick display

object_pk

  • string version of primary key
  • retained for compatibility and indexing

content_type / object_id

Generic relation to any model.

Enables:

  • linking audit logs to any object
  • querying logs per model instance

content_object

GenericForeignKey combining:

  • content_type
  • object_id

changes

  • JSON field
  • stores structured change data

Example:

{ "name": {"old": "Old Name", "new": "New Name"}, "is_active": {"old": true, "new": false} }


ip

  • IP address of request (optional)

user_agent

  • user agent string (optional)

created_at

  • timestamp of audit event
  • defaults to current time

Indexes

AuditLog includes indexes for performance:

  • created_at
  • actor + created_at
  • content_type + object_id
  • action + created_at

These support:

  • time-based queries
  • actor-based queries
  • object-specific queries
  • action filtering

Query Patterns

Common queries include:

Logs for an object

  • filter by content_type and object_id

Logs by actor

  • filter by actor

Logs by action

  • filter by action

Recent activity

  • order by created_at descending

Relationships

flowchart TD
    A[User] -->|actor| B[AuditLog]
    B -->|content_type + object_id| C[Any Model]

Design Principles

Generic and reusable

  • AuditLog works with any model via GenericForeignKey

Append-only

  • audit logs are never updated
  • each entry represents a historical event

Decoupled

  • models do not write audit logs directly
  • services use log_audit helper

Structured changes

  • changes stored as JSON
  • enables flexible diff tracking

What Models Do NOT Do

Core models do not: - enforce permissions - implement business logic - trigger audit logging automatically - validate domain-specific rules

These responsibilities belong to: - services - policies - views


Best Practices

  • always use OrgScopedModel for multi-tenant data
  • use AuditModel where user tracking is needed
  • write audit logs via services, not models
  • keep AuditLog entries small and focused

Future Extensions

Possible improvements: - audit log retention policies - soft-delete support - event streaming (e.g. Kafka) - versioned object snapshots - structured diff utilities


Summary

The core.models module provides foundational building blocks for the backend.

It ensures: - consistent timestamps - strict org scoping - user accountability - system-wide auditability