Skip to content

Commit

Permalink
Merge branch 'game-api-v1' into backend
Browse files Browse the repository at this point in the history
  • Loading branch information
codEnjoyer committed Nov 19, 2023
2 parents cf1ef36 + a991aeb commit c6cc2a2
Show file tree
Hide file tree
Showing 26 changed files with 381 additions and 76 deletions.
4 changes: 2 additions & 2 deletions backend/migrations/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""меняет в модели уровня name на title
Revision ID: da06417476fd
Revises: 29ed19cdffbf
Create Date: 2023-11-19 00:24:59.794292
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'da06417476fd'
down_revision: Union[str, None] = '29ed19cdffbf'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('levels', sa.Column('title', sa.String(length=255), nullable=False))
op.alter_column('levels', 'module_id',
existing_type=sa.UUID(),
nullable=True)
op.drop_column('levels', 'name')
op.alter_column('modules', 'map_id',
existing_type=sa.UUID(),
nullable=True)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('modules', 'map_id',
existing_type=sa.UUID(),
nullable=False)
op.add_column('levels', sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=False))
op.alter_column('levels', 'module_id',
existing_type=sa.UUID(),
nullable=False)
op.drop_column('levels', 'title')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""меняет в модели теории theme на title
Revision ID: 5bbffa09568b
Revises: da06417476fd
Create Date: 2023-11-19 00:49:49.197801
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '5bbffa09568b'
down_revision: Union[str, None] = 'da06417476fd'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('theory_blocks', sa.Column('title', sa.String(), nullable=False))
op.drop_column('theory_blocks', 'theme')
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('theory_blocks', sa.Column('theme', sa.VARCHAR(), autoincrement=False, nullable=False))
op.drop_column('theory_blocks', 'title')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""добавляет связь между задачей и ответами
Revision ID: 43a526a12009
Revises: 5bbffa09568b
Create Date: 2023-11-19 10:35:20.123826
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '43a526a12009'
down_revision: Union[str, None] = '5bbffa09568b'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('questions', sa.Column('task_id', sa.UUID(), nullable=True))
op.create_foreign_key(None, 'questions', 'tasks', ['task_id'], ['id'])
op.add_column('tasks', sa.Column('level_id', sa.UUID(), nullable=True))
op.create_foreign_key(None, 'tasks', 'levels', ['level_id'], ['id'])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'tasks', type_='foreignkey')
op.drop_column('tasks', 'level_id')
op.drop_constraint(None, 'questions', type_='foreignkey')
op.drop_column('questions', 'task_id')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""добавляет связь между вопросами и ответами
Revision ID: e21d5fb84a66
Revises: 43a526a12009
Create Date: 2023-11-19 10:37:12.398132
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'e21d5fb84a66'
down_revision: Union[str, None] = '43a526a12009'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_foreign_key(None, 'answers', 'questions', ['question_id'], ['id'])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'answers', type_='foreignkey')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""временно удаляет таблицу с видео теории
Revision ID: e8496d8a36fc
Revises: e21d5fb84a66
Create Date: 2023-11-19 10:48:35.457329
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'e8496d8a36fc'
down_revision: Union[str, None] = 'e21d5fb84a66'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('theory_videos')
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('theory_videos',
sa.Column('id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('theory_id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('url', sa.TEXT(), autoincrement=False, nullable=False),
sa.ForeignKeyConstraint(['theory_id'], ['theory_blocks.id'], name='theory_videos_theory_id_fkey'),
sa.PrimaryKeyConstraint('id', name='theory_videos_pkey')
)
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""модуль и уровни обязательно привязаны к родителю
Revision ID: 4e3cf7a2acb2
Revises: e8496d8a36fc
Create Date: 2023-11-19 21:46:34.041826
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '4e3cf7a2acb2'
down_revision: Union[str, None] = 'e8496d8a36fc'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('levels', 'module_id',
existing_type=sa.UUID(),
nullable=False)
op.alter_column('modules', 'map_id',
existing_type=sa.UUID(),
nullable=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('modules', 'map_id',
existing_type=sa.UUID(),
nullable=True)
op.alter_column('levels', 'module_id',
existing_type=sa.UUID(),
nullable=True)
# ### end Alembic commands ###
5 changes: 5 additions & 0 deletions backend/src/game/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from repository.level_repository import LevelRepository
from repository.map_repository import MapRepository
from repository.models_repository import ModuleRepository
from services.level_service import LevelService
from services.map_service import MapService
from services.module_service import ModuleService

Expand All @@ -11,5 +13,8 @@ def map_service() -> MapService:
def module_service() -> ModuleService:
return ModuleService(ModuleRepository)


def level_service() -> LevelService:
return LevelService(LevelRepository)
# def users_service():
# return UsersService(UsersRepository)
7 changes: 7 additions & 0 deletions backend/src/game/levels/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import auto, Enum


class LevelStates(Enum):
NotViewed = auto()
Viewed = auto()
Completed = auto()
31 changes: 19 additions & 12 deletions backend/src/game/levels/models.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
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.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
from game.units.tasks.models import TaskUnit
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'

id: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4)
module_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('modules.id'), nullable=False)
name: Mapped[str] = mapped_column(String(length=255), nullable=False)
module_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey('modules.id'))
title: Mapped[str] = mapped_column(String(length=255), nullable=False)

module: Mapped["Module"] = relationship(back_populates='levels')
# theory: Mapped[list["TheoryUnit"]] = relationship(secondary="level_theory_blocks", back_populates='level')
# tasks: Mapped[list["TaskUnit"]] = relationship(secondary="level_tasks", back_populates='level')

theory_units: Mapped[list["TheoryUnit"]] = relationship(
secondary="level_theory_blocks", back_populates='level', lazy='selectin')

task_units: Mapped[list["TaskUnit"]] = relationship(
secondary="level_tasks", back_populates='level', lazy='selectin')

def to_read_schema(self) -> LevelRead:
return LevelRead(id=self.id,
module_id=self.module_id,
title=self.title,
theory_units=[unit.to_read_schema() for unit in self.theory_units],
task_units=[unit.to_read_schema() for unit in self.task_units])


class EmployeesLevel(BaseModel):
Expand Down
25 changes: 15 additions & 10 deletions backend/src/game/levels/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,36 @@
from fastapi import APIRouter

from game.levels.schemas import LevelRead, LevelCreate, LevelUpdate
from utils.types import LevelServiceType

router = APIRouter(prefix="/levels", tags=["Levels"])


@router.get("/")
async def root() -> list[LevelRead]:
return []
async def root(level_service: LevelServiceType) -> list[LevelRead]:
return await level_service.get_all()


@router.get("/{id}")
async def get_level(id: UUID) -> LevelRead:
return LevelRead(id=id, is_accomplished=False)
async def get_level(id: UUID,
level_service: LevelServiceType) -> LevelRead:
return await level_service.get_one(id)


@router.post("/")
async def post_level(level_create: LevelCreate) -> LevelRead:
return LevelRead()
async def post_level(level_create: LevelCreate,
level_service: LevelServiceType) -> LevelRead:
return await level_service.create_one(level_create)


@router.delete("/{id}")
async def delete_level(id: UUID) -> LevelRead:
return LevelRead(id=id, is_accomplished=False)
async def delete_level(id: UUID,
level_service: LevelServiceType) -> LevelRead:
return await level_service.delete_one(id)


@router.patch("/{id}")
async def update_level(id: UUID,
level_update: LevelUpdate) -> LevelRead:
return LevelRead(id=id, is_accomplished=True)
level_update: LevelUpdate,
level_service: LevelServiceType) -> LevelRead:
return await level_service.update_one(id, level_update)
13 changes: 7 additions & 6 deletions backend/src/game/levels/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@

from pydantic import BaseModel, ConfigDict

from game.units.tasks.schemas import TaskUnitRead
from game.units.theory.schemas import TheoryUnitRead


class __LevelBase(BaseModel):
module_id: UUID
title: str
theory_units_id: list[UUID] | None
task_units_id: list[UUID] | None

model_config = ConfigDict(from_attributes=True)


class LevelRead(__LevelBase):
id: UUID
theory_units_id: list[UUID]
task_units_id: list[UUID]
theory_units: list[TheoryUnitRead]
task_units: list[TaskUnitRead]


class LevelCreate(__LevelBase):
# theory_units: list[TheoryUnitRead] | None
# task_units: list[TaskUnitRead] | None
pass


class LevelUpdate(__LevelBase):
module_id: UUID | None = None
title: str | None = None
theory_units_id: list[UUID] | None = None
task_units_id: list[UUID] | None = None
Loading

0 comments on commit c6cc2a2

Please sign in to comment.