add edit resume

This commit is contained in:
ivankirpichnikov
2025-11-22 03:31:17 +03:00
parent d9a3c39980
commit a2a9b8f8c1
9 changed files with 288 additions and 15 deletions
@@ -0,0 +1,56 @@
from template_project.application.common.data_structure import to_data_structure
from template_project.application.common.enums import ExperienceType
from template_project.application.common.identity_provider import IdentityProvider
from template_project.application.common.interactor import to_interactor
from template_project.application.common.unit_of_work import UnitOfWork
from template_project.application.resume.data_gateway import ResumeDataGateway
from template_project.application.resume.entity import ResumeId
from template_project.application.resume.errors import ResumeDoesBelongUserError
@to_data_structure
class _Response:
id: ResumeId
position: str
about_me: str
key_skills: list[str]
experience_type: ExperienceType
@to_interactor
class EditResumeInteractor:
unit_of_work: UnitOfWork
identity_provider: IdentityProvider
resume_data_gateway: ResumeDataGateway
async def execute(
self,
resume_id: ResumeId,
position: str | None,
about_me: str | None,
key_skills: list[str] | None,
experience_type: ExperienceType | None,
) -> _Response:
user = await self.identity_provider.get_current_user()
resume = await self.resume_data_gateway.load(resume_id)
if resume.user_id != user.id:
raise ResumeDoesBelongUserError
if position is not None:
resume.position = position
if about_me is not None:
resume.about_me = about_me
if key_skills is not None:
resume.key_skills = key_skills
if experience_type is not None:
resume.experience_type = experience_type
await self.unit_of_work.commit()
return _Response(
id=resume.id,
position=resume.position,
about_me=resume.about_me,
key_skills=resume.key_skills,
experience_type=resume.experience_type,
)
@@ -18,6 +18,7 @@ class ResumePredictionResponse:
@to_data_structure
class _Response:
id: ResumeId
position: str
about_me: str
key_skills: list[str]
@@ -53,6 +54,7 @@ class GetResumeInteractor:
prediction = None
return _Response(
id=resume.id,
position=resume.position,
about_me=resume.about_me,
key_skills=resume.key_skills,
@@ -7,6 +7,7 @@ from template_project.application.notification_device.interactors.register_devic
)
from template_project.application.notification_device.interactors.send_notification import NotificationInteractor
from template_project.application.resume.interactors.add import AddResumeInteractor
from template_project.application.resume.interactors.edit import EditResumeInteractor
from template_project.application.resume.interactors.get import GetResumeInteractor
from template_project.application.user.profile.interactors.get_profile import GetProfileInteractor
from template_project.application.user.profile.interactors.patch_profile import PatchProfileInteractor
@@ -24,4 +25,5 @@ class InteractorProvider(Provider):
RegisterNotificationDeviceInteractor,
GetResumeInteractor,
AddResumeInteractor,
EditResumeInteractor,
)
+34 -3
View File
@@ -12,6 +12,7 @@ from template_project.application.common.enums import ExperienceType
from template_project.application.resume.entity import ResumeId
from template_project.application.resume.errors import ResumeDoesBelongUserError, ResumeNotFoundError
from template_project.application.resume.interactors.add import AddResumeInteractor
from template_project.application.resume.interactors.edit import EditResumeInteractor
from template_project.application.resume.interactors.get import GetResumeInteractor
security = HTTPBearer()
@@ -66,6 +67,7 @@ class SalaryPrediction(BaseModel):
class ResumeResponse(BaseModel):
id: ResumeId = Field(description="Resume ID")
position: str = Field(description="Job position")
about_me: str = Field(description="About me section")
key_skills: list[str] = Field(description="List of key skills")
@@ -90,6 +92,7 @@ class ResumeResponse(BaseModel):
class ResumeListItem(BaseModel):
id: ResumeId = Field(description="Resume ID")
position: str = Field(description="Job position")
about_me: str = Field(description="About me section")
key_skills: list[str] = Field(description="List of key skills")
@@ -208,6 +211,7 @@ async def get_resume(
) from error
return ResumeResponse(
id=interactor_response.id,
position=interactor_response.position,
about_me=interactor_response.about_me,
key_skills=interactor_response.key_skills,
@@ -266,6 +270,7 @@ class PatchResumeRequest(BaseModel):
class PatchResumeResponse(BaseModel):
id: ResumeId = Field(description="Resume ID")
position: str = Field(description="Job position")
about_me: str = Field(description="About me section")
key_skills: list[str] = Field(description="List of key skills")
@@ -310,11 +315,37 @@ async def get_resume_history(
200: {"description": "Resume updated successfully", "model": PatchResumeResponse},
401: {"description": "Unauthorized - invalid or missing token"},
404: {"description": "Resume not found"},
403: {"descriptipn": "The resume does not belong to you"},
},
)
async def patch_resume(
resume_id: str,
resume_id: ResumeId,
request: PatchResumeRequest,
interactor: FromDishka[EditResumeInteractor],
) -> PatchResumeResponse:
# TODO: Implement resume update
raise NotImplementedError
try:
interactor_response = await interactor.execute(
resume_id=resume_id,
position=request.position,
about_me=request.about_me,
key_skills=request.key_skills,
experience_type=request.experience_type,
)
except ResumeDoesBelongUserError as error:
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail="The resume does not belong to you",
) from error
except ResumeNotFoundError as error:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND,
detail="Resume not found",
) from error
return PatchResumeResponse(
id=interactor_response.id,
position=interactor_response.position,
about_me=interactor_response.about_me,
key_skills=interactor_response.key_skills,
experience_type=interactor_response.experience_type,
)