feat(realestate): 소득 기준 검증 추가 (특별공급 자격 판정)

income_level(도시근로자 월평균 대비 %) 필드를 활용하여 특별공급 자격 검증:
- 신혼부부·생애최초: 160% 이하 (맞벌이 민간분양 상한)
- 신생아: 200% 이하 (맞벌이 기준)
- 청년: 140% 이하
- 다자녀·노부모부양: 소득 기준 없음
- 미입력 시 검증 생략 (기존 동작 유지)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 10:12:21 +09:00
parent caacb072a2
commit f6de95afb6

View File

@@ -54,13 +54,31 @@ _HOUSE_TYPE_MAP = {
}
def _parse_income_pct(profile: Dict[str, Any]) -> float | None:
"""income_level 필드를 float으로 파싱. 미입력·파싱 실패 시 None 반환."""
raw = profile.get("income_level") or ""
try:
return float(str(raw).strip()) if str(raw).strip() else None
except ValueError:
return None
def _check_eligible_types(profile: Dict[str, Any], ann: Dict[str, Any]) -> List[str]:
"""프로필 기반으로 신청 가능한 공급유형 목록을 반환한다."""
"""프로필 기반으로 신청 가능한 공급유형 목록을 반환한다.
소득 기준(도시근로자 월평균소득 대비 %):
신혼부부·생애최초: 160% 이하 (맞벌이 기준, 민간분양 상한)
신생아: 200% 이하 (맞벌이 기준)
청년: 140% 이하
다자녀·노부모: 소득 기준 없음
income_level 미입력 시 소득 검증 생략 (혜택 부여).
"""
eligible: List[str] = []
is_homeless = profile.get("is_homeless", False)
is_speculative = ann.get("is_speculative_area") == "Y"
required_months = 24 if is_speculative else 12
subscription_months = profile.get("subscription_months") or 0
income_pct = _parse_income_pct(profile)
# 일반공급
if is_homeless and profile.get("is_householder") and subscription_months >= required_months:
@@ -68,26 +86,34 @@ def _check_eligible_types(profile: Dict[str, Any], ann: Dict[str, Any]) -> List[
elif is_homeless:
eligible.append("일반2순위")
# 특별공급 — 신혼부부
# NOTE: 소득기준 검증은 향후 구현 예정 (income_level 필드 활용)
# 특별공급 — 신혼부부 (소득 160% 이하)
if profile.get("is_newlywed") and is_homeless:
if income_pct is None or income_pct <= 160:
eligible.append("특별-신혼부부")
# 특별공급 — 생애최초 (소득 160% 이하)
if profile.get("is_first_home") and is_homeless:
if income_pct is None or income_pct <= 160:
eligible.append("특별-생애최초")
# 특별공급 — 다자녀 (소득 기준 없음)
children_count = profile.get("children_count") or 0
if children_count >= 2 and is_homeless:
eligible.append("특별-다자녀")
# 특별공급 — 노부모부양 (소득 기준 없음)
if profile.get("has_dependents") and is_homeless:
eligible.append("특별-노부모부양")
# 특별공급 — 청년 (소득 140% 이하)
age = profile.get("age") or 0
if 19 <= age <= 39 and is_homeless:
if income_pct is None or income_pct <= 140:
eligible.append("특별-청년")
# 특별공급 — 신생아 (소득 200% 이하)
if profile.get("has_newborn") and is_homeless:
if income_pct is None or income_pct <= 200:
eligible.append("특별-신생아")
return eligible