diff --git a/realestate-lab/app/matcher.py b/realestate-lab/app/matcher.py index 3ccd5be..b1699cb 100644 --- a/realestate-lab/app/matcher.py +++ b/realestate-lab/app/matcher.py @@ -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,27 +86,35 @@ 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: - eligible.append("특별-신혼부부") + if income_pct is None or income_pct <= 160: + eligible.append("특별-신혼부부") + # 특별공급 — 생애최초 (소득 160% 이하) if profile.get("is_first_home") and is_homeless: - eligible.append("특별-생애최초") + 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: - eligible.append("특별-청년") + if income_pct is None or income_pct <= 140: + eligible.append("특별-청년") + # 특별공급 — 신생아 (소득 200% 이하) if profile.get("has_newborn") and is_homeless: - eligible.append("특별-신생아") + if income_pct is None or income_pct <= 200: + eligible.append("특별-신생아") return eligible