diff --git a/models/__init__.py b/models/__init__.py index 4e11006..01a265a 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -10,6 +10,6 @@ from .built_in_module import ( # noqa: F401 ) from .deal import Deal as Deal from .project import Project as Project -from .status import Status as Status, CardStatusHistory as CardStatusHistory +from .status import Status as Status, DealStatusHistory as DealStatusHistory configure_mappers() diff --git a/models/deal.py b/models/deal.py index 4adcb63..b63d0d3 100644 --- a/models/deal.py +++ b/models/deal.py @@ -7,7 +7,7 @@ from models.base import BaseModel from models.mixins import SoftDeleteMixin, CreatedAtMixin, IdMixin if TYPE_CHECKING: - from models import Status, Board, CardStatusHistory + from models import Status, Board, DealStatusHistory class Deal(BaseModel, IdMixin, SoftDeleteMixin, CreatedAtMixin): @@ -28,7 +28,7 @@ class Deal(BaseModel, IdMixin, SoftDeleteMixin, CreatedAtMixin): ) board: Mapped["Board"] = relationship(back_populates="deals") - status_history: Mapped[list["CardStatusHistory"]] = relationship( + status_history: Mapped[list["DealStatusHistory"]] = relationship( back_populates="deal", cascade="all, delete-orphan", lazy="noload", diff --git a/models/status.py b/models/status.py index e8902f5..70b5f70 100644 --- a/models/status.py +++ b/models/status.py @@ -20,7 +20,7 @@ class Status(BaseModel, IdMixin, SoftDeleteMixin): board: Mapped["Board"] = relationship(back_populates="statuses") -class CardStatusHistory(BaseModel, IdMixin, CreatedAtMixin): +class DealStatusHistory(BaseModel, IdMixin, CreatedAtMixin): __tablename__ = "status_history" deal_id: Mapped[int] = mapped_column(ForeignKey("deals.id"), nullable=False) diff --git a/repositories/deal.py b/repositories/deal.py index 27b6885..5241a21 100644 --- a/repositories/deal.py +++ b/repositories/deal.py @@ -1,6 +1,6 @@ from sqlalchemy.orm import joinedload -from models import Deal, CardStatusHistory, Board +from models import Deal, Board, DealStatusHistory from repositories.mixins import * from schemas.base import SortDir from schemas.deal import UpdateDealSchema, CreateDealSchema @@ -68,7 +68,7 @@ class DealRepository( if data.status_id and deal.status_id != data.status_id: deal.status_history.append( - CardStatusHistory( + DealStatusHistory( from_status_id=deal.status_id, to_status_id=data.status_id, ) diff --git a/repositories/status.py b/repositories/status.py index 539f863..65aaf42 100644 --- a/repositories/status.py +++ b/repositories/status.py @@ -1,6 +1,6 @@ from sqlalchemy import func -from models import Status, Deal +from models import Status, Deal, DealStatusHistory from repositories.mixins import * from schemas.status import UpdateStatusSchema, CreateStatusSchema @@ -29,3 +29,12 @@ class StatusRepository(RepCrudMixin[Status, CreateStatusSchema, UpdateStatusSche async def update(self, status: Status, data: UpdateStatusSchema) -> Status: return await self._apply_update_data_to_model(status, data, True) + + async def get_status_history(self, deal_id: int) -> list[DealStatusHistory]: + stmt = ( + select(DealStatusHistory) + .where(DealStatusHistory.deal_id == deal_id) + .order_by(DealStatusHistory.created_at) + ) + result = await self.session.execute(stmt) + return list(result.scalars().all()) diff --git a/routers/status.py b/routers/status.py index cabd25f..c9e9b00 100644 --- a/routers/status.py +++ b/routers/status.py @@ -54,3 +54,15 @@ async def delete_status( pk: int = Path(), ): return await StatusService(session).delete(pk) + + +@router.get( + "/history/{dealId}", + response_model=GetStatusHistoryResponse, + operation_id="get_status_history", +) +async def get_status_history( + session: SessionDependency, + deal_id: int = Path(alias="dealId"), +): + return await StatusService(session).get_status_history(deal_id) diff --git a/schemas/status.py b/schemas/status.py index a9e28a2..2f6a10c 100644 --- a/schemas/status.py +++ b/schemas/status.py @@ -1,3 +1,4 @@ +from datetime import datetime from typing import Optional from schemas.base import BaseSchema, BaseResponse @@ -23,6 +24,14 @@ class UpdateStatusSchema(BaseSchema): lexorank: Optional[str] = None +class StatusHistorySchema(BaseSchema): + id: int + created_at: datetime + from_status: StatusSchema + to_status: StatusSchema + deal_id: int + + # endregion # region Requests @@ -57,4 +66,8 @@ class DeleteStatusResponse(BaseResponse): pass +class GetStatusHistoryResponse(BaseSchema): + items: list[StatusHistorySchema] + + # endregion diff --git a/services/status.py b/services/status.py index 8b9a95b..f03b2a1 100644 --- a/services/status.py +++ b/services/status.py @@ -19,3 +19,7 @@ class StatusService( deals_count = await self.repository.get_deals_count(status.id) is_soft_needed: bool = deals_count > 0 return is_soft_needed + + async def get_status_history(self, deal_id: int) -> GetStatusHistoryResponse: + items = await self.repository.get_status_history(deal_id) + return GetStatusHistoryResponse(items=items)