From d3d163ee72966bf01c87be09213a083567967486 Mon Sep 17 00:00:00 2001 From: andrei Date: Tue, 3 Jun 2025 11:39:20 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=BE=D0=BB=D0=B5=20=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API/app/application/teams_repository.py | 5 +++ API/app/contollers/teams_router.py | 28 ++++++++++++++++ ..._0006_добавил_поле_активности_у_команды.py | 32 +++++++++++++++++++ API/app/domain/entities/team.py | 1 + API/app/domain/models/teams.py | 3 +- API/app/infrastructure/teams_service.py | 29 ++++++++++++++++- 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 API/app/database/migrations/versions/61271acdd22f_0006_добавил_поле_активности_у_команды.py diff --git a/API/app/application/teams_repository.py b/API/app/application/teams_repository.py index 48cc633..5a019b9 100644 --- a/API/app/application/teams_repository.py +++ b/API/app/application/teams_repository.py @@ -20,6 +20,11 @@ class TeamsRepository: result = await self.db.execute(stmt) return result.scalars().first() + async def get_active_team(self): + stmt = select(Team).filter_by(is_active=True) + result = await self.db.execute(stmt) + return result.scalars().first() + async def create(self, team: Team) -> Team: self.db.add(team) await self.db.commit() diff --git a/API/app/contollers/teams_router.py b/API/app/contollers/teams_router.py index a6cf332..22769fd 100644 --- a/API/app/contollers/teams_router.py +++ b/API/app/contollers/teams_router.py @@ -25,6 +25,19 @@ async def get_all_teams( return await teams_service.get_all_teams() +@router.get( + '/active/', + response_model=Optional[TeamEntity], + summary='Get active team', + description='Returns active team', +) +async def get_all_teams( + db: AsyncSession = Depends(get_db), +): + teams_service = TeamsService(db) + return await teams_service.get_active_team() + + @router.post( '/', response_model=Optional[TeamEntity], @@ -40,6 +53,21 @@ async def create_team( return await teams_service.create_team(team) +@router.put( + '/{team_id}/set-active/', + response_model=Optional[TeamEntity], + summary='Make team active', + description='Makes team active', +) +async def update_team( + team_id: int, + db: AsyncSession = Depends(get_db), + user=Depends(require_admin), +): + teams_service = TeamsService(db) + return await teams_service.set_active_team(team_id) + + @router.put( '/{team_id}/', response_model=Optional[TeamEntity], diff --git a/API/app/database/migrations/versions/61271acdd22f_0006_добавил_поле_активности_у_команды.py b/API/app/database/migrations/versions/61271acdd22f_0006_добавил_поле_активности_у_команды.py new file mode 100644 index 0000000..3305e52 --- /dev/null +++ b/API/app/database/migrations/versions/61271acdd22f_0006_добавил_поле_активности_у_команды.py @@ -0,0 +1,32 @@ +"""0006_добавил поле активности у команды + +Revision ID: 61271acdd22f +Revises: de2777da99c9 +Create Date: 2025-06-03 11:37:03.183872 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '61271acdd22f' +down_revision: Union[str, None] = 'de2777da99c9' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('teams', sa.Column('is_active', sa.Boolean(), server_default='false', nullable=False)) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('teams', 'is_active') + # ### end Alembic commands ### diff --git a/API/app/domain/entities/team.py b/API/app/domain/entities/team.py index c769bf6..3defb14 100644 --- a/API/app/domain/entities/team.py +++ b/API/app/domain/entities/team.py @@ -11,5 +11,6 @@ class TeamEntity(BaseModel): description: Optional[str] = None logo: Optional[str] = None git_url: Optional[str] = None + is_active: bool profiles: Optional[list[ProfileEntity]] = None diff --git a/API/app/domain/models/teams.py b/API/app/domain/models/teams.py index 8538dad..13b4fa4 100644 --- a/API/app/domain/models/teams.py +++ b/API/app/domain/models/teams.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, VARCHAR, String +from sqlalchemy import Column, VARCHAR, String, Boolean from sqlalchemy.orm import relationship from app.domain.models.base import AdvancedBaseModel @@ -11,5 +11,6 @@ class Team(AdvancedBaseModel): description = Column(VARCHAR(150)) logo = Column(String) git_url = Column(String) + is_active = Column(Boolean, default=False, nullable=False, server_default='false') profiles = relationship("Profile", back_populates="team") diff --git a/API/app/infrastructure/teams_service.py b/API/app/infrastructure/teams_service.py index 317a927..d1cede0 100644 --- a/API/app/infrastructure/teams_service.py +++ b/API/app/infrastructure/teams_service.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Any, Coroutine from fastapi import HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession @@ -19,6 +19,14 @@ class TeamsService: for team in teams ] + async def get_active_team(self) -> Optional[TeamEntity]: + team = await self.teams_repository.get_active_team() + + if not team: + return None + + return self.model_to_entity(team) + async def create_team(self, team: TeamEntity) -> Optional[TeamEntity]: team_model = self.entity_to_model(team) @@ -40,6 +48,23 @@ class TeamsService: return self.model_to_entity(team_model) + async def set_active_team(self, team_id: int) -> TeamEntity: + team_model = await self.teams_repository.get_by_id(team_id) + + if not team_model: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Team not found") + + active_team = await self.teams_repository.get_active_team() + + if active_team: + active_team.is_active = False + await self.teams_repository.update(active_team) + + team_model.is_active = True + team_model = await self.teams_repository.update(team_model) + + return self.model_to_entity(team_model) + async def delete_team(self, team_id: int) -> Optional[TeamEntity]: team_model = await self.teams_repository.get_by_id(team_id) @@ -58,6 +83,7 @@ class TeamsService: description=team_model.description, logo=team_model.logo, git_url=team_model.git_url, + is_active=team_model.is_active, ) @staticmethod @@ -67,6 +93,7 @@ class TeamsService: description=team_entity.description, logo=team_entity.logo, git_url=team_entity.git_url, + is_active=team_entity.is_active, ) if team_entity.id: