# 구조화 레코드 계약 `EvidenceItem.content`는 다양한 원자료를 수용하기 위한 원자적 사실 문장입니다. 회사·직무·기간 같은 핵심 이력을 자유 문장에만 보관하면 정렬, 날짜 검증, 양식 변환이 불안정해지므로 `CandidateProfile.records`에 다음 타입을 선택적으로 병행 저장합니다. | 타입 | 필수 구조 | 의미 | |---|---|---| | `CareerRecord` | 회사, 직무, 기간, 고용형태, 근거 ID | 금전적 보수를 받은 경력 (`paid=true`) | | `ExperienceRecord` | 역할, 기간, 경험 유형, 근거 ID | 프로젝트·봉사 등 무급 경험 (`paid=false`) | | `EducationRecord` | 학교, 학위, 기간, 상태, 근거 ID | 학력·교육 이력 | | `CertificationRecord` | 자격명, 발급기관, 취득일, 근거 ID | 자격·인증 이력 | `EmploymentType`은 채용공고와 경력 레코드가 함께 쓰는 enum입니다. 정규직, 시간제, 기간제, 계약직, 인턴, 프리랜서, 파견직, 기타를 구분합니다. ## 불변 조건 - 모든 레코드는 하나 이상의 기존 `EvidenceItem.evidence_id`를 참조합니다. - 회사·직무·학교·학위·자격명·발급기관·날짜 같은 핵심 값은 연결된 근거의 `content`, `keywords`, `metrics`, `date_range` 정보에서 확인되어야 합니다. - 레코드 ID는 프로필 전체에서 유일하며 하나의 근거 ID는 한 레코드만 소유합니다. - 경력은 `career`, 학력은 `education`, 자격은 `certification` 범주의 근거만 참조합니다. 무급 경험은 프로젝트·봉사·활동 계열 근거만 참조합니다. - 완료된 기간은 종료일이 필수입니다. 시작일 이후의 종료일만 허용하고, 진행 중인 기간은 종료일을 함께 둘 수 없습니다. - 재학 상태는 진행 중 기간과 일치해야 하며 자격 만료일은 취득일보다 빠를 수 없습니다. - 입력 순서에 의존하지 않고 `*_chronological()`이 최신순 정본 뷰를 제공합니다. 날짜는 연, 연월, 연월일 정밀도를 그대로 보존합니다. 입력에 없는 일자를 임의로 만들지 않으며 한국식 표기는 각각 `YYYY`, `YYYY.MM`, `YYYY.MM.DD`입니다. ## 개인정보·출력 경계 구조화 레코드는 현재 로컬 intake 및 검증 계층입니다. LLM에 전달되는 `candidate_facts` whitelist나 Markdown 렌더러에 자동으로 추가되지 않습니다. 따라서 학교명이나 회사명이 `public_blind` 필터, 기밀 근거 차단, 글자 수 제한, `ResumeDraft.fingerprint()`를 우회할 수 없습니다. 향후 구조화 레코드를 초안에 자동 반영하는 materializer는 다음 순서를 지켜야 합니다. 1. 민감·기밀 근거 제외 및 공고별 블라인드 필드 제거 2. 허용된 근거 ID를 가진 `DraftClaim` 생성 3. `ContentPlan` 및 공고 제약과의 참조 무결성 검사 4. 결정적 validator와 독립 품질 평가 수행 5. 승인된 `ResumeDraft` fingerprint에 품질 보고서를 결합한 뒤 렌더 레코드에서 곧바로 Markdown/DOCX 행을 만드는 공개 API는 정본 불변 조건을 깨뜨리므로 제공하지 않습니다.