11package com .leets7th .job_is_be .domain .user .entity ;
22
3+ import com .leets7th .job_is_be .domain .user .enums .ResumeCategory ;
4+ import com .leets7th .job_is_be .domain .user .enums .ResumeFileFormat ;
35import com .leets7th .job_is_be .global .base .BaseEntity ;
46import jakarta .persistence .*;
57import lombok .AccessLevel ;
1012import java .time .LocalDateTime ;
1113
1214/**
13- * 이력서/자소서 파일
15+ * 이력서/자소서 파일 (S3 Presigned URL 업로드, 유형별 1슬롯)
1416 */
1517@ Entity
16- @ Table (name = "resumes" )
18+ @ Table (
19+ name = "resumes" ,
20+ uniqueConstraints = {
21+ @ UniqueConstraint (name = "uk_resumes_user_category" , columnNames = {"user_id" , "category" })
22+ }
23+ )
1724@ Getter
1825@ NoArgsConstructor (access = AccessLevel .PROTECTED )
1926public class Resume extends BaseEntity {
@@ -26,17 +33,19 @@ public class Resume extends BaseEntity {
2633 @ JoinColumn (name = "user_id" , nullable = false )
2734 private User user ;
2835
36+ @ Enumerated (EnumType .STRING )
37+ @ Column (name = "category" , nullable = false , length = 20 )
38+ private ResumeCategory category ;
39+
2940 @ Column (name = "file_name" , nullable = false , length = 255 )
3041 private String fileName ;
3142
43+ @ Enumerated (EnumType .STRING )
3244 @ Column (name = "file_type" , nullable = false , length = 10 )
33- private String fileType ; // PDF, DOCX, HWP, HWPX
34-
35- @ Column (name = "file_url" , nullable = false , length = 500 )
36- private String fileUrl ;
45+ private ResumeFileFormat fileFormat ;
3746
38- @ Column (name = "is_active " , nullable = false )
39- private boolean active ;
47+ @ Column (name = "s3_key " , nullable = false , length = 500 )
48+ private String s3Key ;
4049
4150 // TODO: LocalDateTime → OffsetDateTime으로 통일 필요 (BaseEntity와 타입 불일치)
4251 @ Column (name = "uploaded_at" , nullable = false )
@@ -47,17 +56,21 @@ public class Resume extends BaseEntity {
4756 private LocalDateTime deletedAt ;
4857
4958 @ Builder
50- public Resume (User user , String fileName , String fileType , String fileUrl , LocalDateTime uploadedAt ) {
59+ public Resume (User user , ResumeCategory category , String fileName , ResumeFileFormat fileFormat , String s3Key , LocalDateTime uploadedAt ) {
5160 this .user = user ;
61+ this .category = category ;
5262 this .fileName = fileName ;
53- this .fileType = fileType ;
54- this .fileUrl = fileUrl ;
63+ this .fileFormat = fileFormat ;
64+ this .s3Key = s3Key ;
5565 this .uploadedAt = uploadedAt ;
56- this .active = true ;
5766 }
5867
59- public void delete (LocalDateTime now ) {
60- this .active = false ;
61- this .deletedAt = now ;
68+ /**
69+ * 같은 유형(user+category) 재업로드 시 기존 row를 새 파일 정보로 갱신 (S3 오브젝트 키는 고정이라 그대로 유지)
70+ */
71+ public void replace (String fileName , ResumeFileFormat fileFormat , LocalDateTime uploadedAt ) {
72+ this .fileName = fileName ;
73+ this .fileFormat = fileFormat ;
74+ this .uploadedAt = uploadedAt ;
6275 }
6376}
0 commit comments