feat: deal status history table

This commit is contained in:
2025-09-20 10:07:56 +04:00
parent 44f315b4a0
commit 6b3d124adf
8 changed files with 45 additions and 7 deletions

View File

@ -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()

View File

@ -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",

View File

@ -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)

View File

@ -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,
)

View File

@ -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())

View File

@ -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)

View File

@ -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

View File

@ -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)