geo/backend/app/models/content.py

156 lines
5.1 KiB
Python

import uuid
from datetime import datetime
from sqlalchemy import String, Integer, ForeignKey, Index, func, Text
from sqlalchemy import Uuid
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base, JSONType
class Content(Base):
__tablename__ = "contents"
id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
)
organization_id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
ForeignKey("organizations.id", ondelete="CASCADE"),
nullable=False,
)
project_id: Mapped[uuid.UUID | None] = mapped_column(
Uuid(as_uuid=True),
ForeignKey("lifecycle_projects.id", ondelete="SET NULL"),
nullable=True,
)
title: Mapped[str] = mapped_column(String(500), nullable=False)
content_type: Mapped[str] = mapped_column(String(50), nullable=False)
body: Mapped[str | None] = mapped_column(Text, nullable=True)
status: Mapped[str] = mapped_column(String(20), server_default="draft", nullable=False)
target_platforms: Mapped[list | None] = mapped_column(JSONType, nullable=True)
keywords: Mapped[list | None] = mapped_column(JSONType, nullable=True)
extra_metadata: Mapped[dict | None] = mapped_column("metadata", JSONType, nullable=True)
created_by: Mapped[str | None] = mapped_column(
String(36),
ForeignKey("users.id", ondelete="SET NULL"),
nullable=True,
)
current_version: Mapped[int] = mapped_column(Integer, server_default="1", nullable=False)
created_at: Mapped[datetime] = mapped_column(
server_default=func.now(),
nullable=False,
)
updated_at: Mapped[datetime] = mapped_column(
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
# Relationships
organization: Mapped["Organization"] = relationship(
"Organization", back_populates="contents"
)
project: Mapped["LifecycleProject | None"] = relationship(
"LifecycleProject"
)
creator: Mapped["User | None"] = relationship(
"User", foreign_keys=[created_by]
)
versions: Mapped[list["ContentVersion"]] = relationship(
"ContentVersion", back_populates="content", cascade="all, delete-orphan"
)
reviews: Mapped[list["ContentReview"]] = relationship(
"ContentReview", back_populates="content", cascade="all, delete-orphan"
)
__table_args__ = (
Index("idx_contents_organization_id", "organization_id"),
Index("idx_contents_project_id", "project_id"),
Index("idx_contents_status", "status"),
Index("idx_contents_content_type", "content_type"),
Index("idx_contents_created_by", "created_by"),
)
class ContentVersion(Base):
__tablename__ = "content_versions"
id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
)
content_id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
ForeignKey("contents.id", ondelete="CASCADE"),
nullable=False,
)
version_number: Mapped[int] = mapped_column(Integer, nullable=False)
title: Mapped[str | None] = mapped_column(String(500), nullable=True)
body: Mapped[str | None] = mapped_column(Text, nullable=True)
change_summary: Mapped[str | None] = mapped_column(String(500), nullable=True)
created_by: Mapped[str | None] = mapped_column(
String(36),
ForeignKey("users.id", ondelete="SET NULL"),
nullable=True,
)
created_at: Mapped[datetime] = mapped_column(
server_default=func.now(),
nullable=False,
)
# Relationships
content: Mapped["Content"] = relationship(
"Content", back_populates="versions"
)
creator: Mapped["User | None"] = relationship(
"User", foreign_keys=[created_by]
)
__table_args__ = (
Index("idx_content_versions_content_id", "content_id"),
Index("idx_content_versions_content_version", "content_id", "version_number", unique=True),
)
class ContentReview(Base):
__tablename__ = "content_reviews"
id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
)
content_id: Mapped[uuid.UUID] = mapped_column(
Uuid(as_uuid=True),
ForeignKey("contents.id", ondelete="CASCADE"),
nullable=False,
)
reviewer_id: Mapped[str] = mapped_column(
String(36),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
)
status: Mapped[str] = mapped_column(String(20), nullable=False)
comments: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(
server_default=func.now(),
nullable=False,
)
# Relationships
content: Mapped["Content"] = relationship(
"Content", back_populates="reviews"
)
reviewer: Mapped["User"] = relationship(
"User", foreign_keys=[reviewer_id]
)
__table_args__ = (
Index("idx_content_reviews_content_id", "content_id"),
Index("idx_content_reviews_reviewer_id", "reviewer_id"),
)