You've already forked RekomenciBackend
feat(): openapi docs for resume
This commit is contained in:
@@ -11,10 +11,10 @@ router = APIRouter(route_class=DishkaRoute, tags=["Resume"], dependencies=[Depen
|
|||||||
|
|
||||||
|
|
||||||
class ExperienceTypeEnum(StrEnum):
|
class ExperienceTypeEnum(StrEnum):
|
||||||
NO_EXPERIENCE = "no_experience"
|
NO_EXPERIENCE = "noExperience"
|
||||||
BETWEEN_1_AND_3 = "between_1_and_3"
|
BETWEEN_1_AND_3 = "between1And3"
|
||||||
BETWEEN_3_AND_6 = "between_3_and_6"
|
BETWEEN_3_AND_6 = "between3And6"
|
||||||
MORE_THAN_6 = "more_than_6"
|
MORE_THAN_6 = "moreThan6"
|
||||||
|
|
||||||
|
|
||||||
class CreateResumeRequest(BaseModel):
|
class CreateResumeRequest(BaseModel):
|
||||||
@@ -28,6 +28,11 @@ class CreateResumeRequest(BaseModel):
|
|||||||
experience_type: ExperienceTypeEnum = Field(
|
experience_type: ExperienceTypeEnum = Field(
|
||||||
..., description="Experience type", examples=[ExperienceTypeEnum.BETWEEN_3_AND_6]
|
..., description="Experience type", examples=[ExperienceTypeEnum.BETWEEN_3_AND_6]
|
||||||
)
|
)
|
||||||
|
parent_resume_id: str | None = Field(
|
||||||
|
None,
|
||||||
|
description="ID of parent resume (for creating resume from existing one)",
|
||||||
|
examples=["01234567-89ab-cdef-0123-456789abcdef"],
|
||||||
|
)
|
||||||
|
|
||||||
model_config = {
|
model_config = {
|
||||||
"json_schema_extra": {
|
"json_schema_extra": {
|
||||||
@@ -35,7 +40,8 @@ class CreateResumeRequest(BaseModel):
|
|||||||
"position": "Python Developer",
|
"position": "Python Developer",
|
||||||
"about_me": "Experienced Python developer with 5 years of experience",
|
"about_me": "Experienced Python developer with 5 years of experience",
|
||||||
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
||||||
"experience_type": "between_3_and_6",
|
"experience_type": "between3And6",
|
||||||
|
"parent_resume_id": None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +84,7 @@ class ResumeResponse(BaseModel):
|
|||||||
"position": "Python Developer",
|
"position": "Python Developer",
|
||||||
"about_me": "Experienced Python developer with 5 years of experience",
|
"about_me": "Experienced Python developer with 5 years of experience",
|
||||||
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
||||||
"experience_type": "between_3_and_6",
|
"experience_type": "between3And6",
|
||||||
"prediction": {
|
"prediction": {
|
||||||
"from_salary": "100000",
|
"from_salary": "100000",
|
||||||
"to_salary": "150000",
|
"to_salary": "150000",
|
||||||
@@ -101,7 +107,7 @@ class ResumeListItem(BaseModel):
|
|||||||
"position": "Python Developer",
|
"position": "Python Developer",
|
||||||
"about_me": "Experienced Python developer with 5 years of experience",
|
"about_me": "Experienced Python developer with 5 years of experience",
|
||||||
"key_skills": ["Python", "FastAPI", "PostgreSQL"],
|
"key_skills": ["Python", "FastAPI", "PostgreSQL"],
|
||||||
"experience_type": "between_3_and_6",
|
"experience_type": "between3And6",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +129,7 @@ class GetResumeListResponse(BaseModel):
|
|||||||
"position": "Python Developer",
|
"position": "Python Developer",
|
||||||
"about_me": "Experienced Python developer",
|
"about_me": "Experienced Python developer",
|
||||||
"key_skills": ["Python", "FastAPI"],
|
"key_skills": ["Python", "FastAPI"],
|
||||||
"experience_type": "between_3_and_6",
|
"experience_type": "between3And6",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -147,7 +153,7 @@ class GetResumeHistoryResponse(BaseModel):
|
|||||||
"position": "Python Developer",
|
"position": "Python Developer",
|
||||||
"about_me": "Experienced Python developer",
|
"about_me": "Experienced Python developer",
|
||||||
"key_skills": ["Python", "FastAPI"],
|
"key_skills": ["Python", "FastAPI"],
|
||||||
"experience_type": "between_3_and_6",
|
"experience_type": "between3And6",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -182,7 +188,7 @@ async def create_resume(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
async def get_resume(
|
async def get_resume(
|
||||||
resume_id: str = Field(..., description="Resume ID"),
|
resume_id: str,
|
||||||
) -> ResumeResponse:
|
) -> ResumeResponse:
|
||||||
# TODO: Implement resume retrieval
|
# TODO: Implement resume retrieval
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@@ -205,6 +211,50 @@ async def get_resume_list(
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class PatchResumeRequest(BaseModel):
|
||||||
|
position: str | None = Field(
|
||||||
|
None, min_length=1, max_length=200, description="Job position", examples=["Python Developer"]
|
||||||
|
)
|
||||||
|
about_me: str | None = Field(
|
||||||
|
None, min_length=1, max_length=2000, description="About me section", examples=["Experienced Python developer"]
|
||||||
|
)
|
||||||
|
key_skills: list[str] | None = Field(
|
||||||
|
None, min_length=1, description="List of key skills", examples=[["Python", "FastAPI", "PostgreSQL"]]
|
||||||
|
)
|
||||||
|
experience_type: ExperienceTypeEnum | None = Field(
|
||||||
|
None, description="Experience type", examples=[ExperienceTypeEnum.BETWEEN_3_AND_6]
|
||||||
|
)
|
||||||
|
|
||||||
|
model_config = {
|
||||||
|
"json_schema_extra": {
|
||||||
|
"example": {
|
||||||
|
"position": "Python Developer",
|
||||||
|
"about_me": "Experienced Python developer with 5 years of experience",
|
||||||
|
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
||||||
|
"experience_type": "between3And6",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PatchResumeResponse(BaseModel):
|
||||||
|
position: str = Field(..., description="Job position")
|
||||||
|
about_me: str = Field(..., description="About me section")
|
||||||
|
key_skills: list[str] = Field(..., description="List of key skills")
|
||||||
|
experience_type: ExperienceTypeEnum = Field(..., description="Experience type")
|
||||||
|
|
||||||
|
model_config = {
|
||||||
|
"json_schema_extra": {
|
||||||
|
"example": {
|
||||||
|
"position": "Python Developer",
|
||||||
|
"about_me": "Experienced Python developer with 5 years of experience",
|
||||||
|
"key_skills": ["Python", "FastAPI", "PostgreSQL", "Docker"],
|
||||||
|
"experience_type": "between3And6",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
"/resume/{resume_id}/history",
|
"/resume/{resume_id}/history",
|
||||||
summary="Get resume history",
|
summary="Get resume history",
|
||||||
@@ -216,9 +266,27 @@ async def get_resume_list(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
async def get_resume_history(
|
async def get_resume_history(
|
||||||
resume_id: str = Field(..., description="Resume ID"),
|
resume_id: str,
|
||||||
limit: int = Query(..., ge=1, le=100, description="Number of history items to return", examples=[10]),
|
limit: int = Query(..., ge=1, le=100, description="Number of history items to return", examples=[10]),
|
||||||
offset: int = Query(..., ge=0, description="Number of history items to skip", examples=[0]),
|
offset: int = Query(..., ge=0, description="Number of history items to skip", examples=[0]),
|
||||||
) -> GetResumeHistoryResponse:
|
) -> GetResumeHistoryResponse:
|
||||||
# TODO: Implement resume history retrieval
|
# TODO: Implement resume history retrieval
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@router.patch(
|
||||||
|
"/resume/{resume_id}",
|
||||||
|
summary="Update resume",
|
||||||
|
description="Update resume fields. All fields are optional.",
|
||||||
|
responses={
|
||||||
|
200: {"description": "Resume updated successfully", "model": PatchResumeResponse},
|
||||||
|
401: {"description": "Unauthorized - invalid or missing token"},
|
||||||
|
404: {"description": "Resume not found"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async def patch_resume(
|
||||||
|
resume_id: str,
|
||||||
|
request: PatchResumeRequest,
|
||||||
|
) -> PatchResumeResponse:
|
||||||
|
# TODO: Implement resume update
|
||||||
|
raise NotImplementedError
|
||||||
|
|||||||
@@ -28,9 +28,7 @@ async def test_email_sign_up_creates_user(
|
|||||||
password=DEFAULT_PASSWORD,
|
password=DEFAULT_PASSWORD,
|
||||||
)
|
)
|
||||||
assert is_success_response(response)
|
assert is_success_response(response)
|
||||||
assert response.json() == IsPartialDict(
|
assert response.json() == IsPartialDict(access_token=IsStr())
|
||||||
access_token=IsStr()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@inject
|
@inject
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ async def test_healthcheck(
|
|||||||
) -> None:
|
) -> None:
|
||||||
response = await http_client.get("/healthcheck")
|
response = await http_client.get("/healthcheck")
|
||||||
assert is_success_response(response)
|
assert is_success_response(response)
|
||||||
assert response.json() == IsDict(
|
assert response.json() == IsDict({
|
||||||
{
|
"ok": True,
|
||||||
"ok": True,
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user