Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat resumeupdate #48

Merged
merged 5 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions app/api/v1/routes.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
from fastapi import APIRouter, HTTPException
from app.dto.resume_dto import ResumeRequest, ResumeResponse
from app.dto.resume_modify_dto import UpdateRequestDto,ResumeResponseDto
from app.dto.resume_dto import ResumeRequest, ResumeResponse, UpdateRequestDto,ResumeResponseDto
from app.services.api_service import process_repository
from concurrent.futures import ProcessPoolExecutor
import asyncio
import json
import logging
from app.services.stack_service import generate_techstack
from app.services.gpt_service import generate_aboutme, resume_update
from app.services.data_service import find_field_for_text, update_field_by_path, get_value_by_path
from app.config.settings import settings


from copy import deepcopy
from pydantic import ValidationError

router = APIRouter()


@router.put("/api/ai/resumes", response_model=ResumeResponseDto)
async def update_resume(request: UpdateRequestDto):
try:
Expand All @@ -31,18 +33,58 @@ async def update_resume(request: UpdateRequestDto):
context_data=request.resumeInfo.dict()
)

print(updated_resume)
# return updated_resume

# 업데이트된 결과 확인
print("=== Updated Resume Data ===")
print(updated_resume)
if hasattr(updated_resume, "dict"):
updated_resume_dict = updated_resume.dict()
else:
updated_resume_dict = updated_resume

print("=== Updated Resume 딕트 ===")
print(updated_resume_dict)
print(json.dumps(updated_resume_dict, indent=4, ensure_ascii=False))

# 업데이트된 결과 반환
return updated_resume
# 선택된 텍스트가 어느 필드에 있는지 찾기
print("=== 선택된 텍스트의 필드 찾기 ===")
matching_fields = find_field_for_text(request.resumeInfo.dict(), request.selectedText)
print(f"🔍 매칭된 필드 경로: {matching_fields}")

except Exception as e:
print(f"Error in update_resume: {e}")
raise HTTPException(status_code=500, detail="An error occurred while updating the resume.")
if not matching_fields:
raise HTTPException(status_code=400, detail="Selected text does not match any field in the context data.")


# 원본 데이터를 deepcopy
original_data = deepcopy(request.resumeInfo.dict())

print(original_data)
# return updated_resume
# 수정된 필드만 병합
for field_path in matching_fields:
updated_value = get_value_by_path(updated_resume_dict, field_path)
print(f"✅ 수정된 값 for path {field_path}: {updated_value}")
if updated_value is not None:
update_field_by_path(original_data, field_path, updated_value)

# 병합 후 데이터 확인
print("=== 병합된 최종 데이터 확인 ===")
print(json.dumps(original_data, indent=4, ensure_ascii=False))

# DTO 변환
updated_response = ResumeResponseDto(**original_data)
print("=== DTO 변환 성공 ===")
return updated_response

except ValidationError as e:
print(f"❌ DTO Validation Error: {e.json()}")
raise HTTPException(status_code=422, detail=f"DTO validation failed: {e.json()}")

except Exception as e:
print(f"❌ Error in update_resume: {e}")
raise HTTPException(status_code=500, detail="An error occurred while updating the resume.")

# 이력서 생성 api
@router.post("/api/ai/resumes", response_model=ResumeResponse)
async def generate_resume(request: ResumeRequest):
Expand Down
109 changes: 106 additions & 3 deletions app/dto/resume_dto.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from pydantic import BaseModel, HttpUrl
from typing import List, Union
from app.dto.resume_modify_dto import StarDto, TroubleShootingDto
from typing import List, Union, Optional, Literal


# 요청 데이터 모델
Expand All @@ -14,16 +13,44 @@ class ResumeRequest(BaseModel):

# 응답 데이터 모델 - 프로젝트 정보(공통DTO)
class Project(BaseModel):
# type: str
type: Literal['BASIC'] = "BASIC"
projectName: str
projectStartedAt: str # YYYY-MM-DD 형식
projectEndedAt: str # YYYY-MM-DD 형식
skillSet: str
roleAndTask: List[str] # BASIC 템플릿에서 사용
repoLink: HttpUrl
repoLink: str

class StarDto(BaseModel):
situation: str
task: str
action: str
result: str

class ProjectTitleDto(BaseModel):
projectTitle: str

class RoleAndTaskDto(BaseModel):
roleAndTask: List[str]

class TroubleShootingDto(BaseModel):
problem: str
hypothesis: str
tring: str
result: str

# class Basic(Project):
# type: str = "BASIC"

class StarProject(Project):
# type: str = "STAR"
type: Literal['STAR'] = "STAR"
star: StarDto

class GitfolioProject(Project):
# type: str = "GITFOLIO"
type: Literal['GITFOLIO'] = "GITFOLIO"
troubleShooting: TroubleShootingDto

# gpt 프로젝트 요약문, json형태
Expand All @@ -43,3 +70,79 @@ class ResumeResponse(BaseModel):
techStack: List[str]
aboutMe: str
projects: List[Union[Project, StarProject, GitfolioProject]]

class WorkExperience(BaseModel):
companyName: str
departmentName: str
role: str
workType: str # FULL_TIME, PART_TIME 등
employmentStatus: str # EMPLOYMENT, UNEMPLOYMENT 등
startedAt: str # YYYY-MM 형식
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값

class ProjectResponse(BaseModel):
projectName: str
projectStartedAt: str # YYYY.MM 형식
projectEndedAt: str # YYYY.MM 형식
skillSet: str
projectDescription: str
repoLink: str

class Link(BaseModel):
linkTitle: str
linkUrl: str

class Education(BaseModel):
schoolType: str # UNIVERSITY_BACHELOR 등
schoolName: str
major: str
graduationStatus: str # ATTENDING, GRADUATED 등
startedAt: str # YYYY-MM 형식
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값

class Certificate(BaseModel):
certificateName: str
certificateGrade: str
certificatedAt: str # YYYY-MM 형식
certificateOrganization: str

# 응답 데이터 모델 - 전체 이력서
class ResumeResponseDto(BaseModel):
template: str
resumeId: str
memberId: int
memberName: str
avatarUrl: str
email: str
position: str
techStack: List[str]
aboutMe: str
tags: Optional[List[str]] # null 가능
workExperiences: List[WorkExperience]
# projects: List[ProjectResponse]
projects: List[Union[Project, StarProject, GitfolioProject]]
links: Optional[List[Link]] # null 가능
educations: List[Education]
certificates: List[Certificate]

class updateResumeDto(BaseModel):
template: str
resumeId: str
memberId: int
memberName: str
avatarUrl: str
email: str
position: str
techStack: List[str]
aboutMe: str
tags: Optional[List[str]] # null 가능
workExperiences: List[WorkExperience]
projects: List[Union[Project, StarProject, GitfolioProject]] # 추가된 필드
links: Optional[List[Link]] # null 가능
educations: List[Education]
certificates: List[Certificate]

class UpdateRequestDto(BaseModel):
selectedText: str
requirement: str
resumeInfo: updateResumeDto
133 changes: 68 additions & 65 deletions app/dto/resume_modify_dto.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,78 @@
from pydantic import BaseModel
from typing import List, Optional
# from pydantic import BaseModel
# from typing import List, Optional, Union
# from app.dto.resume_dto import Project, StarProject, GitfolioProject

class WorkExperience(BaseModel):
companyName: str
departmentName: str
role: str
workType: str # FULL_TIME, PART_TIME 등
employmentStatus: str # EMPLOYMENT, UNEMPLOYMENT 등
startedAt: str # YYYY-MM 형식
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값
# class WorkExperience(BaseModel):
# companyName: str
# departmentName: str
# role: str
# workType: str # FULL_TIME, PART_TIME 등
# employmentStatus: str # EMPLOYMENT, UNEMPLOYMENT 등
# startedAt: str # YYYY-MM 형식
# endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값

class ProjectResponse(BaseModel):
projectName: str
projectStartedAt: str # YYYY.MM 형식
projectEndedAt: str # YYYY.MM 형식
skillSet: str
projectDescription: str
repoLink: str
class Link(BaseModel):
linkTitle: str
linkUrl: str
# class ProjectResponse(BaseModel):
# projectName: str
# projectStartedAt: str # YYYY.MM 형식
# projectEndedAt: str # YYYY.MM 형식
# skillSet: str
# projectDescription: str
# repoLink: str

# class Link(BaseModel):
# linkTitle: str
# linkUrl: str

class Education(BaseModel):
schoolType: str # UNIVERSITY_BACHELOR 등
schoolName: str
major: str
graduationStatus: str # ATTENDING, GRADUATED 등
startedAt: str # YYYY-MM 형식
endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값
# class Education(BaseModel):
# schoolType: str # UNIVERSITY_BACHELOR 등
# schoolName: str
# major: str
# graduationStatus: str # ATTENDING, GRADUATED 등
# startedAt: str # YYYY-MM 형식
# endedAt: Optional[str] # YYYY-MM 형식 또는 빈 값

class Certificate(BaseModel):
certificateName: str
certificateGrade: str
certificatedAt: str # YYYY-MM 형식
certificateOrganization: str
# class Certificate(BaseModel):
# certificateName: str
# certificateGrade: str
# certificatedAt: str # YYYY-MM 형식
# certificateOrganization: str

class ResumeResponseDto(BaseModel):
resumeId: str
memberId: int
memberName: str
avatarUrl: str
email: str
position: str
techStack: List[str]
aboutMe: str
tags: Optional[List[str]] # null 가능
workExperiences: List[WorkExperience]
projects: List[ProjectResponse]
links: Optional[List[Link]] # null 가능
educations: List[Education]
certificates: List[Certificate]
# class ResumeResponseDto(BaseModel):
# resumeId: str
# memberId: int
# memberName: str
# avatarUrl: str
# email: str
# position: str
# techStack: List[str]
# aboutMe: str
# tags: Optional[List[str]] # null 가능
# workExperiences: List[WorkExperience]
# # projects: List[ProjectResponse]
# projects: List[Union[Project, StarProject, GitfolioProject]]
# links: Optional[List[Link]] # null 가능
# educations: List[Education]
# certificates: List[Certificate]

class UpdateRequestDto(BaseModel):
selectedText: str
requirement: str
resumeInfo: ResumeResponseDto
# class UpdateRequestDto(BaseModel):
# selectedText: str
# requirement: str
# resumeInfo: ResumeResponseDto

class ProjectTitleDto(BaseModel):
projectTitle: str
# class ProjectTitleDto(BaseModel):
# projectTitle: str

class RoleAndTaskDto(BaseModel):
roleAndTask: List[str]
# class RoleAndTaskDto(BaseModel):
# roleAndTask: List[str]

class TroubleShootingDto(BaseModel):
problem: str
hypothesis: str
tring: str
result: str
# class TroubleShootingDto(BaseModel):
# problem: str
# hypothesis: str
# tring: str
# result: str

class StarDto(BaseModel):
situation: str
task: str
action: str
result: str
# class StarDto(BaseModel):
# situation: str
# task: str
# action: str
# result: str
Loading
Loading