150 lines
6.6 KiB
Python
150 lines
6.6 KiB
Python
import uuid
|
|
from datetime import datetime, timezone
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Integer, Text, UniqueConstraint
|
|
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from ..database import Base
|
|
|
|
|
|
class AdventureEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
user_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
status: Mapped[str] = mapped_column(Text, nullable=False, default="awaiting_first_entry")
|
|
language: Mapped[str] = mapped_column(Text, nullable=False)
|
|
source_language: Mapped[str] = mapped_column(Text, nullable=False)
|
|
competencies: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
|
max_entry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=6)
|
|
entry_story_text_target_length: Mapped[dict] = mapped_column(
|
|
JSONB, nullable=False, default=lambda: {"min": 700, "max": 800}
|
|
)
|
|
title: Mapped[str] = mapped_column(Text, nullable=False, default="Untitled adventure")
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
plot_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
genres: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
|
setting: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
|
vibes: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
|
protagonist: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
|
)
|
|
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class AdventureEntryEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure_entry"
|
|
__table_args__ = (
|
|
UniqueConstraint("adventure_id", "entry_index", name="uq_cyoa_entry_adventure_index"),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
adventure_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("choose_your_own_adventure.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
generated_from_choice_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey(
|
|
"choose_your_own_adventure_entry_possible_choice.id", ondelete="SET NULL"
|
|
),
|
|
nullable=True,
|
|
)
|
|
status: Mapped[str] = mapped_column(Text, nullable=False, default="generating")
|
|
entry_index: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
story_text: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
gamemaster_notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
llm_data: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
|
)
|
|
|
|
|
|
class AdventureEntryPossibleChoiceEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure_entry_possible_choice"
|
|
__table_args__ = (
|
|
UniqueConstraint("entry_id", "index", name="uq_cyoa_choice_entry_index"),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
entry_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
index: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
label: Mapped[str] = mapped_column(Text, nullable=False)
|
|
text: Mapped[str] = mapped_column(Text, nullable=False)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
|
)
|
|
|
|
|
|
class AdventureEntryPossibleChoiceDecisionEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure_entry_possible_choice_decision"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
choice_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey(
|
|
"choose_your_own_adventure_entry_possible_choice.id", ondelete="CASCADE"
|
|
),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
user_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
|
)
|
|
|
|
|
|
class AdventureEntryTranslationEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure_entry_translation"
|
|
__table_args__ = (
|
|
UniqueConstraint(
|
|
"entry_id", "component_type", "target_language",
|
|
name="uq_cyoa_translation_entry_component_lang",
|
|
),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
entry_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
component_type: Mapped[str] = mapped_column(Text, nullable=False, default="story_text")
|
|
target_language: Mapped[str] = mapped_column(Text, nullable=False)
|
|
translated_text: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
|
|
class AdventureEntryAudioEntity(Base):
|
|
__tablename__ = "choose_your_own_adventure_entry_audio"
|
|
__table_args__ = (
|
|
UniqueConstraint("entry_id", "component_type", name="uq_cyoa_audio_entry_component"),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
entry_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("choose_your_own_adventure_entry.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
index=True,
|
|
)
|
|
component_type: Mapped[str] = mapped_column(Text, nullable=False, default="story_text")
|
|
tts_provider: Mapped[str] = mapped_column(Text, nullable=False, default="google_gemini")
|
|
tts_options: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
|
|
file_name: Mapped[str] = mapped_column(Text, nullable=False)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)
|
|
)
|