"""Reusable column mixins. - ``UUIDPrimaryKey`` — UUID surrogate key (no PII in URLs; safe for multi-tenant). - ``Timestamps`` — created/updated audit timestamps (DB-managed). - ``SoftDelete`` — ``deleted_at``; a row is "deleted" when set. A scheduled worker purges rows past the 30-day window (PRD US-080/081). - ``TenantScoped`` — ``tree_id`` FK; every tree-owned row carries it so the privacy engine can enforce isolation uniformly. """ import uuid from datetime import datetime from sqlalchemy import DateTime, ForeignKey, func from sqlalchemy.orm import Mapped, declared_attr, mapped_column class UUIDPrimaryKey: id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) class Timestamps: created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False, ) class SoftDelete: deleted_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, default=None ) class TenantScoped: @declared_attr def tree_id(cls) -> Mapped[uuid.UUID]: # noqa: N805 return mapped_column( ForeignKey("trees.id", ondelete="CASCADE"), nullable=False, index=True )