from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession from inbox.enums import Candidate_application_Status from inbox.models import Inbox from job.candidate.models import ApplicationStageTransitions from job.pipeline.serializers import serialize_stage_transition class Pipeline: def __init__(self,session:AsyncSession): self.session=session async def get_transitions(self,inbox_id=None,transition_id=None): if transition_id: row=await ApplicationStageTransitions.get_by_id(self.session,transition_id) if not row: raise HTTPException(status_code=404,detail="Transition not found") return serialize_stage_transition(row) if inbox_id is None: raise HTTPException(status_code=400,detail="transition_id or inbox_id is required") rows=await ApplicationStageTransitions.fetch_by_inbox(self.session,int(inbox_id)) return [serialize_stage_transition(r) for r in rows] async def change_stage(self,inbox_id,to_stage,current_user,change_reason=None): inbox=await Inbox.get_inbox_with_message(self.session,inbox_id) if not inbox: raise HTTPException(status_code=404,detail="Inbox not found") message=inbox.messages if not message: raise HTTPException(status_code=404,detail="Inbox message not found") try: stage=Candidate_application_Status(to_stage) except ValueError: raise HTTPException(status_code=422,detail="Invalid to_stage") current=message.application_status from_stage=current.value if isinstance(current,Candidate_application_Status) else str(current) if from_stage==stage.value: raise HTTPException(status_code=400,detail="already at stage") changed_by=None if isinstance(current_user,dict) and current_user.get("id"): changed_by=ApplicationStageTransitions._as_uuid(current_user.get("id")) await ApplicationStageTransitions.close_open(self.session,inbox.id,commit=False) transition_data={ "inbox_id":inbox.id, "from_stage":from_stage, "to_stage":stage.value, "changed_by":changed_by, "actor_kind":"user", "change_reason":change_reason, } transition=await ApplicationStageTransitions.insert_transition( self.session, transition_data, commit=False, ) message.application_status=stage self.session.add(message) await self.session.commit() return { "inbox_id":inbox.id, "application_status":stage.value, "transition":serialize_stage_transition(transition), }