Files
govoplan-views/src/govoplan_views/backend/db/models.py
T

200 lines
6.7 KiB
Python

from __future__ import annotations
import uuid
from datetime import datetime
from typing import Any
from sqlalchemy import (
Boolean,
DateTime,
ForeignKey,
Index,
Integer,
JSON,
String,
Text,
UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from govoplan_core.db.base import Base, TimestampMixin
def new_uuid() -> str:
return str(uuid.uuid4())
class ViewDefinition(Base, TimestampMixin):
__tablename__ = "view_definitions"
__table_args__ = (
UniqueConstraint(
"scope_key",
"definition_key",
name="uq_view_definition_scope_key",
),
Index("ix_view_definitions_tenant_status", "tenant_id", "status"),
Index("ix_view_definitions_scope", "scope_type", "scope_id"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
scope_type: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
scope_id: Mapped[str | None] = mapped_column(String(255), nullable=True, index=True)
scope_key: Mapped[str] = mapped_column(String(300), nullable=False, index=True)
definition_key: Mapped[str] = mapped_column(String(120), nullable=False)
name: Mapped[str] = mapped_column(String(200), nullable=False)
description: Mapped[str | None] = mapped_column(Text, nullable=True)
status: Mapped[str] = mapped_column(
String(24), default="draft", nullable=False, index=True
)
current_revision: Mapped[int] = mapped_column(Integer, default=1, nullable=False)
published_revision_id: Mapped[str | None] = mapped_column(
String(36),
nullable=True,
index=True,
)
created_by: Mapped[str | None] = mapped_column(
String(255), nullable=True, index=True
)
updated_by: Mapped[str | None] = mapped_column(
String(255), nullable=True, index=True
)
deleted_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True),
nullable=True,
index=True,
)
revisions: Mapped[list["ViewRevision"]] = relationship(
back_populates="definition",
cascade="all, delete-orphan",
order_by="ViewRevision.revision",
)
assignments: Mapped[list["ViewAssignment"]] = relationship(
back_populates="definition",
cascade="all, delete-orphan",
)
class ViewRevision(Base, TimestampMixin):
__tablename__ = "view_revisions"
__table_args__ = (
UniqueConstraint(
"definition_id",
"revision",
name="uq_view_revision_number",
),
Index("ix_view_revisions_definition", "definition_id", "revision"),
Index("ix_view_revisions_contract", "surface_contract_version"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
definition_id: Mapped[str] = mapped_column(
ForeignKey("view_definitions.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
revision: Mapped[int] = mapped_column(Integer, nullable=False)
surface_contract_version: Mapped[str] = mapped_column(String(20), nullable=False)
visible_surface_ids: Mapped[list[str]] = mapped_column(
JSON, default=list, nullable=False
)
presentation: Mapped[dict[str, Any]] = mapped_column(
JSON, default=dict, nullable=False
)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
created_by: Mapped[str | None] = mapped_column(
String(255), nullable=True, index=True
)
definition: Mapped[ViewDefinition] = relationship(back_populates="revisions")
class ViewAssignment(Base, TimestampMixin):
__tablename__ = "view_assignments"
__table_args__ = (
UniqueConstraint(
"target_key",
"definition_id",
"mode",
name="uq_view_assignment_target_definition_mode",
),
Index("ix_view_assignments_tenant_active", "tenant_id", "is_active"),
Index("ix_view_assignments_target", "scope_type", "scope_id"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
scope_type: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
scope_id: Mapped[str | None] = mapped_column(String(255), nullable=True, index=True)
target_key: Mapped[str] = mapped_column(String(320), nullable=False, index=True)
definition_id: Mapped[str] = mapped_column(
ForeignKey("view_definitions.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
revision_id: Mapped[str | None] = mapped_column(
ForeignKey("view_revisions.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
mode: Mapped[str] = mapped_column(
String(20), default="available", nullable=False, index=True
)
priority: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
is_active: Mapped[bool] = mapped_column(
Boolean, default=True, nullable=False, index=True
)
metadata_: Mapped[dict[str, Any]] = mapped_column(
"metadata",
JSON,
default=dict,
nullable=False,
)
created_by: Mapped[str | None] = mapped_column(
String(255), nullable=True, index=True
)
updated_by: Mapped[str | None] = mapped_column(
String(255), nullable=True, index=True
)
definition: Mapped[ViewDefinition] = relationship(back_populates="assignments")
revision: Mapped[ViewRevision | None] = relationship()
class ViewPreference(Base, TimestampMixin):
__tablename__ = "view_preferences"
__table_args__ = (
UniqueConstraint(
"tenant_id",
"account_id",
name="uq_view_preference_tenant_account",
),
Index("ix_view_preferences_tenant_account", "tenant_id", "account_id"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
account_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
selection_kind: Mapped[str] = mapped_column(
String(20),
default="auto",
nullable=False,
index=True,
)
view_id: Mapped[str | None] = mapped_column(
ForeignKey("view_definitions.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
__all__ = [
"ViewAssignment",
"ViewDefinition",
"ViewPreference",
"ViewRevision",
"new_uuid",
]