db_schema_v1
작성일: 2026-04-18
기준 문서: /home/ubuntu/workspace/autonomous-sales-ops/requirements/requirements_v1.md
상태: v1 초안
1. 목표
주임사 등록 사업자 대상 등록임대 계약신고 반자동 MVP를 위한 DB 스키마를 정의한다.
핵심 원칙
- 기존 sales_ops.db(SQLite)를 확장하는 방식으로 간다.
- prospects/opportunities 같은 기존 테이블은 유지한다.
- 새 기능은 계약 사건 중심으로 설계한다.
- 파일은 계약 사건과 제출 작업에 귀속된다.
- 접수번호/필증/후속 일정까지 한 흐름으로 저장한다.
2. 기존 테이블 재사용 방침
기존 테이블
- prospects
- opportunities
- outbound_messages
- inbound_messages
- approvals
- payment_events
- deliveries
재사용 원칙
- prospects는 상위 사업자/고객 엔터티로 재사용 가능
- opportunities는 영업 단계라서 신고 운영 본체로는 직접 쓰지 않음
- 새 기능은 별도 신고 운영 테이블군으로 분리
3. 새 테이블 목록
1. landlord_profiles
2. rental_properties
3. contract_events
4. contract_files
5. filing_jobs
6. filing_job_files
7. filing_results
8. followup_tasks
9. audit_logs
4. 테이블 상세
4.1 landlord_profiles
목적
- 임대사업자 기본 정보 저장
- 주임사 등록 여부와 사업자 유형을 여기서 고정
주요 컬럼
- id INTEGER PRIMARY KEY
- prospect_id INTEGER NULL
- business_type TEXT NOT NULL
- individual / corporate
- is_registered_landlord INTEGER NOT NULL DEFAULT 0
- business_registration_status TEXT NOT NULL DEFAULT 'unknown'
- business_registration_number TEXT
- landlord_name TEXT NOT NULL
- contact_name TEXT
- phone TEXT
- email TEXT
- notes TEXT
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_landlord_profiles_prospect_id
- idx_landlord_profiles_registered
주의
- is_registered_landlord = 1 인 경우만 등록임대 계약신고 흐름 진입 가능
4.2 rental_properties
목적
- 주택 단위 정보 저장
- 등록번호, 주소, 의무임대기간, 보증보험 상태 저장
주요 컬럼
- id INTEGER PRIMARY KEY
- landlord_profile_id INTEGER NOT NULL
- property_name TEXT
- road_address TEXT NOT NULL
- jibun_address TEXT
- registered_number TEXT
- registration_document_path TEXT
- mandatory_rental_period_start TEXT
- mandatory_rental_period_end TEXT
- guarantee_insurance_status TEXT DEFAULT 'unknown'
- guarantee_insurance_provider TEXT
- bookkeeping_registration_status TEXT DEFAULT 'unknown'
- property_status TEXT DEFAULT 'active'
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_rental_properties_landlord
- idx_rental_properties_registered_number
주의
- registered_number가 없으면 등록임대 계약신고 패키지 생성 시 경고
4.3 contract_events
목적
- 계약 단위 사건 저장
- 신규/변경/재계약/묵시적 갱신을 사건으로 관리
주요 컬럼
- id INTEGER PRIMARY KEY
- landlord_profile_id INTEGER NOT NULL
- rental_property_id INTEGER NOT NULL
- event_type TEXT NOT NULL
- new_contract / amended_contract / renewal / implied_renewal
- event_status TEXT NOT NULL DEFAULT 'draft'
- draft / classified / ready_for_filing / filed / failed / cancelled
- contract_signed_at TEXT
- lease_start_date TEXT
- lease_end_date TEXT
- deposit_amount INTEGER DEFAULT 0
- monthly_rent INTEGER DEFAULT 0
- tenant_name TEXT
- tenant_phone TEXT
- change_summary TEXT
- previous_contract_event_id INTEGER NULL
- extracted_data_json TEXT
- corrected_data_json TEXT
- filing_required INTEGER NOT NULL DEFAULT 0
- filing_required_reason TEXT
- rtms_check_required INTEGER NOT NULL DEFAULT 0
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_contract_events_property
- idx_contract_events_event_type
- idx_contract_events_status
주의
- filing_required = 1 이어야 filing_jobs 생성 가능
- extracted_data_json / corrected_data_json 으로 OCR 원본과 사용자 보정값 분리
4.4 contract_files
목적
- 계약 사건에 귀속되는 원본 파일 저장
주요 컬럼
- id INTEGER PRIMARY KEY
- contract_event_id INTEGER NOT NULL
- file_kind TEXT NOT NULL
- contract_pdf / standard_contract / registration_doc / change_proof / screenshot / receipt / certificate / other
- file_path TEXT NOT NULL
- original_name TEXT
- mime_type TEXT
- uploaded_by TEXT DEFAULT 'user'
- user / system / agent
- ocr_status TEXT DEFAULT 'pending'
- pending / completed / failed / skipped
- ocr_text TEXT
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_contract_files_event
- idx_contract_files_kind
4.5 filing_jobs
목적
- 실제 신고 작업 단위 저장
- 렌트홈/지자체 제출 준비 상태와 진행 상태 관리
주요 컬럼
- id INTEGER PRIMARY KEY
- contract_event_id INTEGER NOT NULL
- channel TEXT NOT NULL
- renthome / local_government / rtms_reference
- job_status TEXT NOT NULL DEFAULT 'queued'
- queued / package_ready / awaiting_login / filling / awaiting_final_approval / submitted / result_collected / failed
- filing_due_at TEXT
- package_json TEXT
- checklist_json TEXT
- assigned_agent TEXT
- requires_human_approval INTEGER NOT NULL DEFAULT 1
- started_at TEXT
- submitted_at TEXT
- completed_at TEXT
- error_message TEXT
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_filing_jobs_contract_event
- idx_filing_jobs_status
- idx_filing_jobs_channel
4.6 filing_job_files
목적
- filing job 단위 첨부/결과 파일 연결
주요 컬럼
- id INTEGER PRIMARY KEY
- filing_job_id INTEGER NOT NULL
- contract_file_id INTEGER NULL
- file_role TEXT NOT NULL
- attachment / generated_packet / result_receipt / result_certificate / capture
- file_path TEXT NOT NULL
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_filing_job_files_job
4.7 filing_results
목적
- 제출 결과 저장
- 접수번호/필증/화면 캡처/오류를 구조화
주요 컬럼
- id INTEGER PRIMARY KEY
- filing_job_id INTEGER NOT NULL
- submission_status TEXT NOT NULL
- success / partial / failed
- receipt_number TEXT
- certificate_file_path TEXT
- receipt_file_path TEXT
- result_capture_path TEXT
- result_message TEXT
- collected_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_filing_results_job
- idx_filing_results_receipt
4.8 followup_tasks
목적
- 신고 후 후속 의무 일정 생성
주요 컬럼
- id INTEGER PRIMARY KEY
- contract_event_id INTEGER NOT NULL
- filing_job_id INTEGER NULL
- task_kind TEXT NOT NULL
- insurance_check / rent_increase_check / renewal_followup / amendment_followup / erasure_followup
- task_status TEXT NOT NULL DEFAULT 'pending'
- pending / in_progress / done / cancelled
- due_at TEXT
- note TEXT
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_followup_tasks_contract
- idx_followup_tasks_kind
- idx_followup_tasks_due_at
4.9 audit_logs
목적
- 누가 언제 무엇을 바꿨는지 감사로그 저장
주요 컬럼
- id INTEGER PRIMARY KEY
- entity_type TEXT NOT NULL
- entity_id INTEGER NOT NULL
- action TEXT NOT NULL
- actor_type TEXT NOT NULL
- user / system / agent / admin
- actor_id TEXT
- payload_json TEXT
- created_at TEXT DEFAULT CURRENT_TIMESTAMP
인덱스
- idx_audit_logs_entity
- idx_audit_logs_created_at
5. 관계도
- prospects 1 : N landlord_profiles
- landlord_profiles 1 : N rental_properties
- landlord_profiles 1 : N contract_events
- rental_properties 1 : N contract_events
- contract_events 1 : N contract_files
- contract_events 1 : N filing_jobs
- filing_jobs 1 : N filing_job_files
- filing_jobs 1 : 1 filing_results (v1에서는 1건 가정)
- contract_events 1 : N followup_tasks
6. 상태 흐름
contract_events.event_status
- draft
- classified
- ready_for_filing
- filed
- failed
- cancelled
filing_jobs.job_status
- queued
- package_ready
- awaiting_login
- filling
- awaiting_final_approval
- submitted
- result_collected
- failed
7. v1 저장 예시
계약 업로드 직후
- contract_events.event_status = draft
- contract_files 여러 건 생성
- OCR 결과는 contract_files.ocr_text 또는 contract_events.extracted_data_json 저장
사용자 보정 후
- contract_events.corrected_data_json 저장
- contract_events.filing_required = 1
- contract_events.event_status = ready_for_filing
- filing_jobs 1건 생성
제출 직전
- filing_jobs.job_status = awaiting_final_approval
- requires_human_approval = 1
제출 완료 후
- filing_jobs.job_status = submitted
- filing_results 생성
- followup_tasks 생성
- contract_events.event_status = filed
8. 기존 db.py 반영 원칙
- 기존 SCHEMA 문자열 아래에 새 CREATE TABLE들을 추가
- 기존 테이블은 건드리지 않음
- 마이그레이션 도구가 없으므로 v1은 CREATE TABLE IF NOT EXISTS 방식 유지
- 추후 ALTER TABLE 필요 시 별도 migration_v1 문서 작성
9. 구현 순서
1. app/db.py에 새 테이블 추가
2. 최소 CRUD용 Pydantic 모델 설계
3. 계약 등록 API 구현
4. 패키지 생성 API 구현
5. 결과 업로드 API 구현
6. followup_tasks 자동 생성 연결
7. 테스트 추가
10. 바로 다음 작업
- api_spec_v1.md 작성
- 각 엔드포인트가 어느 테이블을 읽고 쓰는지 명시