feat: patch and get statuses endpoints

This commit is contained in:
2025-08-04 18:48:58 +04:00
parent 298e82d3d1
commit be1ea4009d
16 changed files with 146 additions and 15 deletions

View File

@ -20,6 +20,7 @@ app.add_middleware(
routers_list = [
routes.project_router,
routes.board_router,
routes.status_router,
routes.deal_router,
]
for router in routers_list:

View File

@ -1 +1,4 @@
from .board import BoardRepository as BoardRepository
from .deal import DealRepository as DealRepository
from .project import ProjectRepository as ProjectRepository
from .status import StatusRepository as StatusRepository

View File

@ -1,5 +1,4 @@
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from models import Board
from repositories.base import BaseRepository
@ -8,10 +7,8 @@ from schemas.board import UpdateBoardSchema
class BoardRepository(BaseRepository):
async def get_all(self, project_id: int) -> list[Board]:
stmt = (
select(Board)
.where(Board.is_deleted.is_(False), Board.project_id == project_id)
.options(selectinload(Board.statuses))
stmt = select(Board).where(
Board.is_deleted.is_(False), Board.project_id == project_id
)
result = await self.session.execute(stmt)
return list(result.scalars().all())

31
repositories/status.py Normal file
View File

@ -0,0 +1,31 @@
from sqlalchemy import select
from models import Status
from repositories.base import BaseRepository
from schemas.status import UpdateStatusSchema
class StatusRepository(BaseRepository):
async def get_all(self, board_id: int) -> list[Status]:
stmt = (
select(Status)
.where(Status.is_deleted.is_(False), Status.board_id == board_id)
)
result = await self.session.execute(stmt)
return list(result.scalars().all())
async def get_by_id(self, status_id: int) -> Status | None:
stmt = select(Status).where(
Status.id == status_id, Status.is_deleted.is_(False)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
async def update(self, status: Status, data: UpdateStatusSchema) -> Status:
status.lexorank = data.lexorank if data.lexorank else status.lexorank
status.name = data.name if data.name else status.name
self.session.add(status)
await self.session.commit()
await self.session.refresh(status)
return status

View File

@ -1,3 +1,4 @@
from .project import project_router as project_router
from .board import board_router as board_router
from .deal import deal_router as deal_router
from .project import project_router as project_router
from .status import status_router as status_router

View File

@ -2,7 +2,7 @@ from fastapi import APIRouter, Path
from backend.dependecies import SessionDependency
from schemas.board import GetBoardsResponse, UpdateBoardRequest, UpdateBoardResponse
from services.board import BoardService
from services import BoardService
board_router = APIRouter(
prefix="/board",

View File

@ -2,7 +2,7 @@ from fastapi import APIRouter, Path
from backend.dependecies import SessionDependency
from schemas.deal import GetDealsResponse
from services.deal import DealService
from services import DealService
deal_router = APIRouter(
prefix="/deal",

View File

@ -2,7 +2,7 @@ from fastapi import APIRouter
from backend.dependecies import SessionDependency
from schemas.project import GetProjectsResponse
from services.project import ProjectService
from services import ProjectService
project_router = APIRouter(
prefix="/project",

39
routes/status.py Normal file
View File

@ -0,0 +1,39 @@
from fastapi import APIRouter, Path
from backend.dependecies import SessionDependency
from schemas.status import (
UpdateStatusRequest,
UpdateStatusResponse,
GetStatusesResponse,
)
from services import StatusService
status_router = APIRouter(
prefix="/status",
tags=["status"],
)
@status_router.get(
"/{boardId}",
response_model=GetStatusesResponse,
operation_id="get_statuses",
)
async def get_statuses(
session: SessionDependency,
board_id: int = Path(alias="boardId"),
):
return await StatusService(session).get_statuses(board_id)
@status_router.patch(
"/{statusId}",
response_model=UpdateStatusResponse,
operation_id="update_status",
)
async def update_status(
session: SessionDependency,
request: UpdateStatusRequest,
status_id: int = Path(alias="statusId"),
):
return await StatusService(session).update_status(status_id, request)

View File

@ -1,5 +1,4 @@
from schemas.base import BaseSchema, BaseResponse
from schemas.status import StatusSchema
# region Entity
@ -12,7 +11,6 @@ class BaseBoardSchema(BaseSchema):
class BoardSchema(BaseBoardSchema):
id: int
lexorank: str
statuses: list[StatusSchema]
class UpdateBoardSchema(BaseSchema):

View File

@ -1,4 +1,7 @@
from schemas.base import BaseSchema
from schemas.base import BaseSchema, BaseResponse
# region Entities
class BaseStatusSchema(BaseSchema):
@ -8,3 +11,33 @@ class BaseStatusSchema(BaseSchema):
class StatusSchema(BaseStatusSchema):
id: int
lexorank: str
class UpdateStatusSchema(BaseSchema):
name: str | None = None
lexorank: str | None = None
# endregion
# region Requests
class UpdateStatusRequest(BaseSchema):
status: UpdateStatusSchema
# endregion
# region Responses
class GetStatusesResponse(BaseSchema):
statuses: list[StatusSchema]
class UpdateStatusResponse(BaseResponse):
pass
# endregion

View File

@ -1 +1,4 @@
from .board import BoardService as BoardService
from .deal import DealService as DealService
from .project import ProjectService as ProjectService
from .status import StatusService as StatusService

View File

@ -1,7 +1,7 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from repositories.board import BoardRepository
from repositories import BoardRepository
from schemas.board import (
GetBoardsResponse,
BoardSchema,

View File

@ -1,6 +1,6 @@
from sqlalchemy.ext.asyncio import AsyncSession
from repositories.deal import DealRepository
from repositories import DealRepository
from schemas.deal import GetDealsResponse, DealSchema

View File

@ -1,6 +1,6 @@
from sqlalchemy.ext.asyncio import AsyncSession
from repositories.project import ProjectRepository
from repositories import ProjectRepository
from schemas.project import GetProjectsResponse, ProjectSchema

25
services/status.py Normal file
View File

@ -0,0 +1,25 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from repositories import StatusRepository
from schemas.board import UpdateBoardResponse
from schemas.status import UpdateStatusRequest, GetStatusesResponse, StatusSchema
class StatusService:
def __init__(self, session: AsyncSession):
self.repository = StatusRepository(session)
async def get_statuses(self, board_id: int) -> GetStatusesResponse:
statuses = await self.repository.get_all(board_id)
return GetStatusesResponse(
statuses=[StatusSchema.model_validate(status) for status in statuses]
)
async def update_status(self, status_id: int, request: UpdateStatusRequest):
status = await self.repository.get_by_id(status_id)
if not status:
raise HTTPException(status_code=404, detail="Статус не найден")
await self.repository.update(status, request.status)
return UpdateBoardResponse(message="Статус успешно обновлен")