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 = [ routers_list = [
routes.project_router, routes.project_router,
routes.board_router, routes.board_router,
routes.status_router,
routes.deal_router, routes.deal_router,
] ]
for router in routers_list: 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 .project import ProjectRepository as ProjectRepository
from .status import StatusRepository as StatusRepository

View File

@ -1,5 +1,4 @@
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import selectinload
from models import Board from models import Board
from repositories.base import BaseRepository from repositories.base import BaseRepository
@ -8,10 +7,8 @@ from schemas.board import UpdateBoardSchema
class BoardRepository(BaseRepository): class BoardRepository(BaseRepository):
async def get_all(self, project_id: int) -> list[Board]: async def get_all(self, project_id: int) -> list[Board]:
stmt = ( stmt = select(Board).where(
select(Board) Board.is_deleted.is_(False), Board.project_id == project_id
.where(Board.is_deleted.is_(False), Board.project_id == project_id)
.options(selectinload(Board.statuses))
) )
result = await self.session.execute(stmt) result = await self.session.execute(stmt)
return list(result.scalars().all()) 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 .board import board_router as board_router
from .deal import deal_router as deal_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 backend.dependecies import SessionDependency
from schemas.board import GetBoardsResponse, UpdateBoardRequest, UpdateBoardResponse from schemas.board import GetBoardsResponse, UpdateBoardRequest, UpdateBoardResponse
from services.board import BoardService from services import BoardService
board_router = APIRouter( board_router = APIRouter(
prefix="/board", prefix="/board",

View File

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

View File

@ -2,7 +2,7 @@ from fastapi import APIRouter
from backend.dependecies import SessionDependency from backend.dependecies import SessionDependency
from schemas.project import GetProjectsResponse from schemas.project import GetProjectsResponse
from services.project import ProjectService from services import ProjectService
project_router = APIRouter( project_router = APIRouter(
prefix="/project", 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.base import BaseSchema, BaseResponse
from schemas.status import StatusSchema
# region Entity # region Entity
@ -12,7 +11,6 @@ class BaseBoardSchema(BaseSchema):
class BoardSchema(BaseBoardSchema): class BoardSchema(BaseBoardSchema):
id: int id: int
lexorank: str lexorank: str
statuses: list[StatusSchema]
class UpdateBoardSchema(BaseSchema): 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): class BaseStatusSchema(BaseSchema):
@ -8,3 +11,33 @@ class BaseStatusSchema(BaseSchema):
class StatusSchema(BaseStatusSchema): class StatusSchema(BaseStatusSchema):
id: int id: int
lexorank: str 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 .project import ProjectService as ProjectService
from .status import StatusService as StatusService

View File

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

View File

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

View File

@ -1,6 +1,6 @@
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from repositories.project import ProjectRepository from repositories import ProjectRepository
from schemas.project import GetProjectsResponse, ProjectSchema 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="Статус успешно обновлен")