diff --git a/backend/migrations/env.py b/backend/migrations/env.py index 38798ad..79d9992 100644 --- a/backend/migrations/env.py +++ b/backend/migrations/env.py @@ -34,9 +34,9 @@ from game.modules.models import Module from game.levels.models import Level, LevelTheory, LevelTask from game.units.tasks.models import TaskUnit, EmployeesTask -from game.units.tasks.questions.models import Question, Answer +from game.units.tasks.questions.models import Question, AnswerOption from game.units.tasks.proofs.models import Proof, ProofVideos, ProofImages -from game.units.theory.models import TheoryUnit, TheoryVideo +from game.units.theory.models import TheoryUnit # , TheoryVideo from users.models import User from users.tutors.models import Tutor diff --git a/backend/src/game/levels/enums.py b/backend/src/game/levels/enums.py new file mode 100644 index 0000000..02d64dd --- /dev/null +++ b/backend/src/game/levels/enums.py @@ -0,0 +1,7 @@ +from enum import auto, Enum + + +class LevelStates(Enum): + NotViewed = auto() + Viewed = auto() + Completed = auto() diff --git a/backend/src/game/levels/models.py b/backend/src/game/levels/models.py index 673332b..0132daa 100644 --- a/backend/src/game/levels/models.py +++ b/backend/src/game/levels/models.py @@ -1,14 +1,14 @@ -import enum import typing import uuid -from sqlalchemy import String, Boolean, UUID, ForeignKey, Enum +from sqlalchemy import String, UUID, ForeignKey from sqlalchemy.dialects import postgresql -from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy from sqlalchemy.orm import Mapped, mapped_column, relationship from database import BaseModel +from game.levels.enums import LevelStates from game.levels.schemas import LevelRead +from game.units import TaskUnit, TheoryUnit if typing.TYPE_CHECKING: from game.modules.models import Module @@ -16,12 +16,6 @@ from game.units.theory.models import TheoryUnit -class LevelStates(enum.Enum): - NotViewed = enum.auto() - Viewed = enum.auto() - Completed = enum.auto() - - class Level(BaseModel): __tablename__ = 'levels' diff --git a/backend/src/game/levels/schemas.py b/backend/src/game/levels/schemas.py index 971b613..57f8081 100644 --- a/backend/src/game/levels/schemas.py +++ b/backend/src/game/levels/schemas.py @@ -20,8 +20,9 @@ class LevelRead(__LevelBase): class LevelCreate(__LevelBase): - theory_units: list[TheoryUnitRead] | None - task_units: list[TaskUnitRead] | None + # theory_units: list[TheoryUnitRead] | None + # task_units: list[TaskUnitRead] | None + pass class LevelUpdate(__LevelBase): diff --git a/backend/src/game/units/__init__.py b/backend/src/game/units/__init__.py new file mode 100644 index 0000000..ebdf5e2 --- /dev/null +++ b/backend/src/game/units/__init__.py @@ -0,0 +1,2 @@ +from .tasks import TaskUnit +from .theory import TheoryUnit diff --git a/backend/src/game/units/tasks/__init__.py b/backend/src/game/units/tasks/__init__.py index d4284f4..540523f 100644 --- a/backend/src/game/units/tasks/__init__.py +++ b/backend/src/game/units/tasks/__init__.py @@ -1 +1 @@ -from .models import TaskUnit, TaskTypes, TaskStates, EmployeesTask +from .models import TaskUnit, EmployeesTask diff --git a/backend/src/game/units/tasks/enums.py b/backend/src/game/units/tasks/enums.py new file mode 100644 index 0000000..35f65b1 --- /dev/null +++ b/backend/src/game/units/tasks/enums.py @@ -0,0 +1,12 @@ +from enum import Enum, auto + + +class TaskTypes(Enum): + Test = auto() + + +class TaskStates(Enum): + NotViewed = auto() + Viewed = auto() + Submitted = auto() + Finished = auto() diff --git a/backend/src/game/units/tasks/models.py b/backend/src/game/units/tasks/models.py index 6d70184..0af2b6c 100644 --- a/backend/src/game/units/tasks/models.py +++ b/backend/src/game/units/tasks/models.py @@ -1,5 +1,4 @@ import uuid -import enum from typing import TYPE_CHECKING from sqlalchemy import UUID, Integer, ForeignKey, Boolean @@ -7,22 +6,13 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship from database import BaseModel +from .enums import TaskTypes, TaskStates from .schemas import TaskUnitRead if TYPE_CHECKING: from game.levels.models import Level from questions.models import Question -class TaskTypes(enum.Enum): - Test = enum.auto() - - -class TaskStates(enum.Enum): - NotViewed = enum.auto() - Viewed = enum.auto() - Submitted = enum.auto() - Finished = enum.auto() - class TaskUnit(BaseModel): __tablename__ = 'tasks' @@ -30,10 +20,11 @@ class TaskUnit(BaseModel): id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4) type: Mapped[TaskTypes] = mapped_column(postgresql.ENUM(TaskTypes, name='task_types'), nullable=False, default=TaskTypes.Test) + level_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('levels.id'), default=uuid.uuid4, nullable=True) requires_review: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) score_reward: Mapped[int] = mapped_column(Integer, nullable=False, default=1) - # questions: Mapped[list["Question"]] = relationship() + questions: Mapped[list["Question"]] = relationship(back_populates='task') level: Mapped[list["Level"]] = relationship(secondary="level_tasks", back_populates='task_units') def to_read_schema(self) -> TaskUnitRead: diff --git a/backend/src/game/units/tasks/questions/models.py b/backend/src/game/units/tasks/questions/models.py index 4447494..00e46da 100644 --- a/backend/src/game/units/tasks/questions/models.py +++ b/backend/src/game/units/tasks/questions/models.py @@ -2,7 +2,7 @@ import enum from typing import TYPE_CHECKING -from sqlalchemy import UUID, Enum, String +from sqlalchemy import UUID, Enum, String, ForeignKey from sqlalchemy.dialects import postgresql from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -21,21 +21,22 @@ class Question(BaseModel): __tablename__ = 'questions' id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4) + task_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('tasks.id'), default=uuid.uuid4, nullable=True) type: Mapped[QuestionTypes] = mapped_column( postgresql.ENUM(QuestionTypes, name='question_types'), nullable=False, default=QuestionTypes.SingleChoice) question: Mapped[str] = mapped_column(String, nullable=False, default="Вопрос!") correct_answer_id: Mapped[uuid.UUID] = mapped_column(UUID, default=uuid.uuid4) task: Mapped["TaskUnit"] = relationship(back_populates='questions') - possible_answers: Mapped[list["Answer"]] = relationship(back_populates='question') - correct_answers: Mapped[list["Answer"]] = relationship(back_populates='question') + possible_answers: Mapped[list["AnswerOption"]] = relationship(back_populates='question') + correct_answers: Mapped[list["AnswerOption"]] = relationship(back_populates='question') -class Answer(BaseModel): +class AnswerOption(BaseModel): __tablename__ = 'answers' id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4) - question_id: Mapped[uuid.UUID] = mapped_column(UUID, default=uuid.uuid4) + question_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('questions.id'), default=uuid.uuid4) content: Mapped[str] = mapped_column(String, nullable=False, default='Ответ?') - question: Mapped["Question"] = relationship(back_populates='answers') + question: Mapped["Question"] = relationship(back_populates='possible_answers') diff --git a/backend/src/game/units/tasks/schemas.py b/backend/src/game/units/tasks/schemas.py index 8d6ff63..5475148 100644 --- a/backend/src/game/units/tasks/schemas.py +++ b/backend/src/game/units/tasks/schemas.py @@ -1,10 +1,9 @@ -import typing from uuid import UUID from pydantic import BaseModel, ConfigDict from game.units.tasks.questions.schemas import QuestionRead, QuestionCreate, QuestionUpdate -from game.units.tasks import TaskTypes +from game.units.tasks.enums import TaskTypes class __TaskUnitBase(BaseModel): diff --git a/backend/src/game/units/theory/__init__.py b/backend/src/game/units/theory/__init__.py new file mode 100644 index 0000000..fba643e --- /dev/null +++ b/backend/src/game/units/theory/__init__.py @@ -0,0 +1 @@ +from .models import TheoryUnit diff --git a/backend/src/game/units/theory/models.py b/backend/src/game/units/theory/models.py index 56ae5d5..17e23e3 100644 --- a/backend/src/game/units/theory/models.py +++ b/backend/src/game/units/theory/models.py @@ -28,11 +28,11 @@ def to_read_model(self) -> TheoryUnitRead: content=self.content) -class TheoryVideo(BaseModel): - __tablename__ = 'theory_videos' - - id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4) - theory_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('theory_blocks.id'), nullable=False) - url: Mapped[URL] = mapped_column(URLType, nullable=False) - - theory: Mapped["TheoryUnit"] = relationship(back_populates="theory_video") +# class TheoryVideo(BaseModel): +# __tablename__ = 'theory_videos' +# +# id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4) +# theory_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('theory_blocks.id'), nullable=False) +# url: Mapped[URL] = mapped_column(URLType, nullable=False) +# +# theory: Mapped["TheoryUnit"] = relationship(back_populates="theory_video") diff --git a/backend/src/main.py b/backend/src/main.py index ed5c7a0..40a7b40 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -2,7 +2,7 @@ from fastapi.responses import RedirectResponse from fastapi.middleware.cors import CORSMiddleware -# from game.levels.router import router as levels_router +from game.levels.router import router as levels_router from game.modules.router import router as modules_router from game.map.router import router as map_router # from game.units.tasks.router import router as tasks_router @@ -54,7 +54,7 @@ async def unprotected_route(): include_routers( - # levels_router, + levels_router, modules_router, map_router, # tasks_router,