"""Permission template model — reusable permission presets for entity types. Templates define default sharing rules that can be applied to entities. When applied, they automatically create entity_permissions entries. """ from __future__ import annotations import uuid from datetime import datetime from sqlalchemy import ( CheckConstraint, DateTime, String, func, ) from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import UUID as PGUUID from sqlalchemy.orm import Mapped, mapped_column from app.core.db import Base, TenantMixin class PermissionTemplate(Base, TenantMixin): """Reusable permission template for entity types. When applied to an entity, the template evaluates trigger_condition and auto_share_with to create entity_permissions entries. Fields: - name: Human-readable template name - entity_type: Which entity type this template applies to - trigger_condition: JSONB conditions that must be met for auto-apply - auto_share_with: JSONB list of {principal_type, principal_id, level} to share with - level: Default permission level for this template """ __tablename__ = "permission_templates" __table_args__ = ( CheckConstraint( "level IN ('read', 'write', 'admin', 'delete')", name="ck_pt_level", ), ) id: Mapped[uuid.UUID] = mapped_column( PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) name: Mapped[str] = mapped_column(String(200), nullable=False) entity_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True) trigger_condition: Mapped[dict | None] = mapped_column(JSONB, nullable=True, default=None) auto_share_with: Mapped[list | None] = mapped_column(JSONB, nullable=True, default=None) level: Mapped[str] = mapped_column(String(20), nullable=False, default="read") created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now() ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now(), )