53 lines
2.4 KiB
Python
53 lines
2.4 KiB
Python
"""Модели для кодовых испытаний внутри миссий."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import List, Optional
|
||
|
||
from sqlalchemy import Boolean, ForeignKey, Integer, String, Text, UniqueConstraint
|
||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||
|
||
from app.models.base import Base, TimestampMixin
|
||
|
||
|
||
class CodingChallenge(Base, TimestampMixin):
|
||
"""Шаг миссии с заданием на программирование."""
|
||
|
||
__tablename__ = "coding_challenges"
|
||
__table_args__ = (
|
||
# Порядок внутри миссии должен быть уникальным, чтобы упрощать проверку последовательности.
|
||
UniqueConstraint("mission_id", "order", name="uq_coding_challenge_order"),
|
||
)
|
||
|
||
id: Mapped[int] = mapped_column(primary_key=True)
|
||
mission_id: Mapped[int] = mapped_column(ForeignKey("missions.id"), nullable=False, index=True)
|
||
order: Mapped[int] = mapped_column(Integer, nullable=False)
|
||
title: Mapped[str] = mapped_column(String(160), nullable=False)
|
||
prompt: Mapped[str] = mapped_column(Text, nullable=False)
|
||
starter_code: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||
expected_output: Mapped[str] = mapped_column(Text, nullable=False)
|
||
|
||
mission = relationship("Mission", back_populates="coding_challenges")
|
||
attempts: Mapped[List["CodingAttempt"]] = relationship(
|
||
"CodingAttempt", back_populates="challenge", cascade="all, delete-orphan"
|
||
)
|
||
|
||
|
||
class CodingAttempt(Base, TimestampMixin):
|
||
"""История запусков кода пилота для конкретного задания."""
|
||
|
||
__tablename__ = "coding_attempts"
|
||
|
||
id: Mapped[int] = mapped_column(primary_key=True)
|
||
challenge_id: Mapped[int] = mapped_column(ForeignKey("coding_challenges.id"), nullable=False)
|
||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, index=True)
|
||
code: Mapped[str] = mapped_column(Text, nullable=False)
|
||
stdout: Mapped[str] = mapped_column(Text, nullable=False, default="")
|
||
stderr: Mapped[str] = mapped_column(Text, nullable=False, default="")
|
||
exit_code: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
||
is_passed: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||
|
||
challenge = relationship("CodingChallenge", back_populates="attempts")
|
||
user = relationship("User", back_populates="coding_attempts")
|
||
|