/* 1. 사용자 테이블 */
CREATE TABLE USER (
user_id BIGINT PRIMARY KEY,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
/* 2. 자소서 테이블 */
CREATE TABLE RESUME (
resume_id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
job_category VARCHAR(50) NOT NULL,
question TEXT NOT NULL,
original_content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES USER(user_id)
);
/* 3. AI 첨삭 테이블 (비동기 상태 포함) */
CREATE TABLE FEEDBACK (
feedback_id BIGINT PRIMARY KEY,
resume_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL COMMENT 'PENDING, PROCESSING, COMPLETED, FAILED',
edited_content TEXT,
improvement_points TEXT COMMENT 'JSON format',
error_message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (resume_id) REFERENCES RESUME(resume_id)
);
/* 4. 심층 평가 테이블 (평가 대상 구분 포함) */
CREATE TABLE EVALUATION (
evaluation_id BIGINT PRIMARY KEY,
resume_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL COMMENT 'PENDING, PROCESSING, COMPLETED, FAILED',
target_type VARCHAR(20) NOT NULL COMMENT 'ORIGINAL or FEEDBACK',
target_feedback_id BIGINT COMMENT 'Nullable: Linked if target is FEEDBACK',
score_job_fit INT,
score_problem_solving INT,
score_growth_potential INT,
score_communication INT,
total_avg_score FLOAT,
risk_elements TEXT COMMENT 'JSON format',
qualitative_feedback TEXT,
error_message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (resume_id) REFERENCES RESUME(resume_id),
FOREIGN KEY (target_feedback_id) REFERENCES FEEDBACK(feedback_id)
);
/* 5. 버전 관리 테이블 (변경 사유 포함) */
CREATE TABLE VERSION_CONTROL (
version_id BIGINT PRIMARY KEY,
resume_id BIGINT NOT NULL,
version_number INT NOT NULL,
content_snapshot TEXT NOT NULL,
change_reason VARCHAR(50) COMMENT 'APPLY_FEEDBACK, MANUAL_UPDATE',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (resume_id) REFERENCES RESUME(resume_id)
);

https://www.erdcloud.com/d/kdLT7cgzqusFLK5Gw
erDiagram
%% User Entity
USER {
bigint user_id PK
string email "Unique"
string password
datetime created_at
}
%% Resume Entity
RESUME {
bigint resume_id PK
bigint user_id FK
string job_category
text question
text original_content "CLOB"
datetime created_at
datetime updated_at
}
%% Feedback Entity (AI Editor)
FEEDBACK {
bigint feedback_id PK
bigint resume_id FK
string status "PENDING/COMPLETED/FAILED"
text edited_content "CLOB"
json improvement_points
text error_message
datetime created_at
}
%% Evaluation Entity (AI Evaluator)
EVALUATION {
bigint evaluation_id PK
bigint resume_id FK
string status "PENDING/COMPLETED/FAILED"
string target_type "ORIGINAL/FEEDBACK"
bigint target_feedback_id FK "Nullable"
int score_job_fit
int score_problem_solving
int score_growth_potential
int score_communication
float total_avg_score
json risk_elements
text qualitative_feedback
text error_message
datetime created_at
}
%% Version Control Entity
VERSION_CONTROL {
bigint version_id PK
bigint resume_id FK
int version_number
text content_snapshot "CLOB"
string change_reason "APPLY_FEEDBACK etc"
datetime created_at
}
%% Relationships
USER ||--o{ RESUME : "writes"
RESUME ||--o{ FEEDBACK : "has"
RESUME ||--o{ EVALUATION : "evaluated_by"
RESUME ||--o{ VERSION_CONTROL : "history"
FEEDBACK |o--o{ EVALUATION : "target_source"

이 표는 앞서 확정된 v1.2 (Final) 로직(비동기 상태, 평가 타겟 구분, 백업 사유 포함)이 모두 반영된 최종본
설명: 서비스의 기본 계정 정보를 관리합니다.
| 논리명 | 물리명 (Column) | 데이터 타입 | Null 허용 | PK / FK | 설명 및 비고 |
|---|---|---|---|---|---|
| 사용자 ID | user_id | BIGINT | NO | PK | Auto Increment |
| 이메일 | email | VARCHAR(100) | NO | 유니크(Unique) 제약 조건 필수 | |
| 비밀번호 | password | VARCHAR(255) | NO | Bcrypt 등으로 암호화 저장 | |
| 가입일시 | created_at | DATETIME | NO | DEFAULT CURRENT_TIMESTAMP |
설명: 사용자가 작성한 자기소개서의 원본 데이터를 저장합니다.
| 논리명 | 물리명 (Column) | 데이터 타입 | Null 허용 | PK / FK | 설명 및 비고 |
|---|---|---|---|---|---|
| 자소서 ID | resume_id | BIGINT | NO | PK | Auto Increment |
| 사용자 ID | user_id | BIGINT | NO | FK | USER.user_id 참조 |
| 직무 카테고리 | job_category | VARCHAR(50) | NO | 예: BACKEND, FRONTEND, SALES | |
| 문항 (질문) | question | TEXT | NO | 기업의 자소서 문항 내용 | |
| 원본 내용 | original_content | TEXT | NO | (중요) 사용자가 작성한 원문 | |
| 생성일시 | created_at | DATETIME | NO | ||
| 수정일시 | updated_at | DATETIME | YES | 마지막 수정 시간 기록 |
설명: LLM A가 수행한 첨삭 결과와 비동기 작업 상태를 관리합니다.
| 논리명 | 물리명 (Column) | 데이터 타입 | Null 허용 | PK / FK | 설명 및 비고 |
|---|---|---|---|---|---|
| 첨삭 ID | feedback_id | BIGINT | NO | PK | Auto Increment |
| 자소서 ID | resume_id | BIGINT | NO | FK | RESUME.resume_id 참조 |
| 진행 상태 | status | VARCHAR(20) | NO | PENDING, PROCESSING, COMPLETED, FAILED | |
| 첨삭 내용 | edited_content | TEXT | YES | 작업 완료(COMPLETED) 시 저장 | |
| 개선 포인트 | improvement_points | JSON | YES | 수정 이유 및 핵심 조언 (JSON 배열) | |
| 에러 메시지 | error_message | TEXT | YES | FAILED 상태일 때 에러 원인 기록 | |
| 생성일시 | created_at | DATETIME | NO | 요청 시각 |
설명: LLM B의 평가 점수를 저장하며, 평가 대상(원본 vs 첨삭본)을 구분합니다.
| 논리명 | 물리명 (Column) | 데이터 타입 | Null 허용 | PK / FK | 설명 및 비고 |
|---|---|---|---|---|---|
| 평가 ID | evaluation_id | BIGINT | NO | PK | Auto Increment |
| 자소서 ID | resume_id | BIGINT | NO | FK | RESUME.resume_id 참조 |
| 진행 상태 | status | VARCHAR(20) | NO | PENDING, PROCESSING, COMPLETED, FAILED | |
| 평가 대상 유형 | target_type | VARCHAR(20) | NO | 'ORIGINAL'(원본) 또는 'FEEDBACK'(첨삭본) | |
| 대상 첨삭 ID | target_feedback_id | BIGINT | YES | FK | target_type이 'FEEDBACK'일 때만 값 존재 |
| 직무 적합성 | score_job_fit | INT | YES | 0 ~ 100점 | |
| 문제 해결력 | score_problem_solving | INT | YES | 0 ~ 100점 | |
| 성장 가능성 | score_growth_potential | INT | YES | 0 ~ 100점 | |
| 의사소통 | score_communication | INT | YES | 0 ~ 100점 | |
| 종합 평균 | total_avg_score | FLOAT | YES | 소수점 포함 평균 점수 | |
| 위험 요소 | risk_elements | JSON | YES | 감점 요인 리스트 | |
| 정성 피드백 | qualitative_feedback | TEXT | YES | 줄글 형태의 종합 평가 코멘트 | |
| 에러 메시지 | error_message | TEXT | YES | 실패 시 원인 기록 | |
| 생성일시 | created_at | DATETIME | NO |
설명: 자소서 수정 이력을 저장하고, 백업이 발생한 원인을 추적합니다.
| 논리명 | 물리명 (Column) | 데이터 타입 | Null 허용 | PK / FK | 설명 및 비고 |
|---|---|---|---|---|---|
| 버전 ID | version_id | BIGINT | NO | PK | Auto Increment |
| 자소서 ID | resume_id | BIGINT | NO | FK | RESUME.resume_id 참조 |
| 버전 번호 | version_number | INT | NO | 1부터 시작하여 증가 (1, 2, 3...) | |
| 스냅샷 내용 | content_snapshot | TEXT | NO | 수정 직전의 original_content 백업 | |
| 변경 사유 | change_reason | VARCHAR(50) | YES | 예: 'APPLY_FEEDBACK', 'MANUAL_UPDATE' | |
| 생성일시 | created_at | DATETIME | NO | 백업된 시각 |