Files
web-page-backend/docs/superpowers/specs/2026-04-05-realestate-lab-design.md
gahusb 65ffdec7d2 docs: realestate-lab 설계 스펙 문서 추가
청약 공고 자동 수집 + 프로필 기반 자격 매칭 서비스 설계.
공공데이터포털 API 연동, 독립 서비스 분리, 매칭 엔진 정의.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 20:10:31 +09:00

12 KiB

realestate-lab 설계 스펙

부동산 청약 공고 자동 수집 + 프로필 기반 자격 매칭 서비스


1. 개요

공공데이터포털(한국부동산원 청약홈 분양정보 API)에서 청약 공고를 자동 수집하고, 사용자 프로필 기반으로 지원 가능 여부를 자동 판별하는 독립 서비스.

핵심 목표:

  • 수동 공고 등록 없이 자동 수집 → DB 저장
  • 프로필 기반 자격 매칭 → 지원 가능한 청약만 필터링
  • 프론트에서 "새 공고 N건" 확인 → 향후 텔레그램 알림 확장

2. 서비스 아키텍처

독립 서비스 구조

realestate-lab/                 # 포트 18800
├── app/
│   ├── main.py                 # FastAPI 앱 + APScheduler
│   ├── db.py                   # SQLite CRUD (realestate.db)
│   ├── collector.py            # 공공데이터포털 API 수집기
│   ├── matcher.py              # 프로필 기반 자격 매칭 엔진
│   └── models.py               # Pydantic 요청/응답 모델
├── Dockerfile
└── requirements.txt

수집 흐름

APScheduler (매일 09:00)
  → collector.py: 청약홈 API 5개 엔드포인트 호출
  → DB에 신규 공고 upsert (HOUSE_MANAGE_NO + PBLANC_NO 기준)
  → matcher.py: 프로필 매칭 → 적격 공고에 match_status 부여
  → 신규 매칭 공고 카운트 → (향후) 텔레그램 알림

3. 데이터 소스

공공데이터포털 — 한국부동산원_청약홈 분양정보 조회 서비스

  • Base URL: https://api.odcloud.kr/api
  • 서비스 키: DATA_GO_KR_API_KEY 환경변수
  • 일 호출 제한: 40,000건
  • 데이터 포맷: JSON

수집 대상 API 엔드포인트

엔드포인트 설명
/ApplyhomeInfoDetailSvc/v1/getAPTLttotPblancDetail APT 분양정보 상세
/ApplyhomeInfoDetailSvc/v1/getUrbtyOfctlLttotPblancDetail 오피스텔/도시형/민간임대 상세
/ApplyhomeInfoDetailSvc/v1/getRemndrLttotPblancDetail 잔여세대 상세
/ApplyhomeInfoDetailSvc/v1/getPblPvtRentLttotPblancDetail 공공지원 민간임대 상세
/ApplyhomeInfoDetailSvc/v1/getOPTLttotPblancDetail 임의공급 상세

주택형별 상세 API (모델별 세대수·분양가)

엔드포인트 설명
/ApplyhomeInfoDetailSvc/v1/getAPTLttotPblancMdl APT 주택형별
/ApplyhomeInfoDetailSvc/v1/getUrbtyOfctlLttotPblancMdl 오피스텔 주택형별
/ApplyhomeInfoDetailSvc/v1/getRemndrLttotPblancMdl 잔여세대 주택형별
/ApplyhomeInfoDetailSvc/v1/getPblPvtRentLttotPblancMdl 공공지원 민간임대 주택형별
/ApplyhomeInfoDetailSvc/v1/getOPTLttotPblancMdl 임의공급 주택형별

공통 쿼리 파라미터

  • page (기본: 1), perPage (기본: 100)
  • serviceKey — 인코딩된 API 키
  • cond[RCRIT_PBLANC_DE::GTE] / cond[RCRIT_PBLANC_DE::LTE] — 모집공고일 범위 필터

4. DB 스키마 (realestate.db)

announcements (청약 공고)

컬럼 타입 설명
id INTEGER PK 자동 증가
house_manage_no TEXT NOT NULL 주택관리번호
pblanc_no TEXT NOT NULL 공고번호
house_nm TEXT 주택명
house_secd TEXT 주택구분코드 (01:APT, 02:오피스텔, 04:무순위 등)
house_dtl_secd TEXT 주택상세구분코드 (01:민영, 03:국민 등)
rent_secd TEXT 분양구분 (0:분양, 1:임대)
region_code TEXT 공급지역코드
region_name TEXT 공급지역명
address TEXT 공급위치
total_units INTEGER 공급규모
rcrit_date TEXT 모집공고일
receipt_start TEXT 청약접수시작일
receipt_end TEXT 청약접수종료일
spsply_start TEXT 특별공급 접수시작일
spsply_end TEXT 특별공급 접수종료일
gnrl_rank1_start TEXT 1순위 접수시작일
gnrl_rank1_end TEXT 1순위 접수종료일
winner_date TEXT 당첨자발표일
contract_start TEXT 계약시작일
contract_end TEXT 계약종료일
homepage_url TEXT 홈페이지
pblanc_url TEXT 공고 URL
constructor TEXT 시공사
developer TEXT 시행사
move_in_month TEXT 입주예정월
is_speculative_area TEXT 투기과열지구
is_price_cap TEXT 분양가상한제
contact TEXT 문의처
status TEXT 청약예정/청약중/결과발표/완료 (자동 계산)
source TEXT auto/manual
created_at TEXT
updated_at TEXT
  • UNIQUE 제약: (house_manage_no, pblanc_no)
  • INDEX: idx_realestate_status on status
  • INDEX: idx_realestate_region on region_name

announcement_models (주택형별 상세)

컬럼 타입 설명
id INTEGER PK
house_manage_no TEXT FK → announcements
pblanc_no TEXT FK → announcements
model_no TEXT 모델번호
house_ty TEXT 주택형 (84A 등)
supply_area REAL 공급면적(㎡)
general_units INTEGER 일반공급 세대수
special_units INTEGER 특별공급 세대수
multi_child_units INTEGER 다자녀
newlywed_units INTEGER 신혼부부
first_life_units INTEGER 생애최초
old_parent_units INTEGER 노부모부양
institution_units INTEGER 기관추천
youth_units INTEGER 청년
newborn_units INTEGER 신생아
top_amount INTEGER 분양최고금액(만원)
  • UNIQUE: (house_manage_no, pblanc_no, model_no)

user_profile (사용자 청약 프로필)

컬럼 타입 설명
id INTEGER PK 항상 1 (단일 사용자)
name TEXT 이름
age INTEGER 나이
is_homeless BOOLEAN 무주택 여부
is_householder BOOLEAN 세대주 여부
subscription_months INTEGER 청약통장 가입개월수
subscription_amount INTEGER 청약통장 납입총액(만원)
family_members INTEGER 세대원 수
has_dependents BOOLEAN 부양가족 유무
children_count INTEGER 미성년 자녀수
is_newlywed BOOLEAN 신혼부부 여부
marriage_months INTEGER 혼인기간(개월)
has_newborn BOOLEAN 2세 이하 자녀 유무
is_first_home BOOLEAN 생애최초 해당 여부
income_level TEXT 소득수준 (100%이하/100130%/130160%)
preferred_regions TEXT 관심지역 JSON 배열
preferred_types TEXT 관심주택유형 JSON 배열
min_area REAL 최소 희망면적(㎡)
max_area REAL 최대 희망면적(㎡)
max_price INTEGER 최대 분양가(만원)
updated_at TEXT

match_results (매칭 결과)

컬럼 타입 설명
id INTEGER PK
announcement_id INTEGER FK → announcements
model_id INTEGER FK → announcement_models (nullable)
match_score INTEGER 매칭 점수 (0~100)
match_reasons TEXT 매칭 사유 JSON 배열
eligible_types TEXT 지원 가능 유형 JSON 배열
is_new BOOLEAN 신규 매칭 여부 (알림용)
created_at TEXT
  • UNIQUE: (announcement_id, model_id)

5. API 엔드포인트

청약 공고

메서드 경로 설명
GET /api/realestate/announcements 공고 목록 (필터: region, status, house_type, matched_only, sort, page, size)
GET /api/realestate/announcements/{id} 공고 상세 (주택형별 포함)
POST /api/realestate/announcements 수동 공고 등록
PUT /api/realestate/announcements/{id} 공고 수정
DELETE /api/realestate/announcements/{id} 공고 삭제

수집 관리

메서드 경로 설명
POST /api/realestate/collect 수동 수집 트리거
GET /api/realestate/collect/status 마지막 수집 결과 (수집일시, 신규건수, 에러)

프로필

메서드 경로 설명
GET /api/realestate/profile 내 프로필 조회
PUT /api/realestate/profile 프로필 수정 (upsert)

매칭

메서드 경로 설명
GET /api/realestate/matches 매칭 결과 목록 (점수순, 신규 우선)
POST /api/realestate/matches/refresh 매칭 재계산
PATCH /api/realestate/matches/{id}/read 신규 알림 읽음 처리

대시보드

메서드 경로 설명
GET /api/realestate/dashboard 요약 (진행중 공고수, 신규 매칭수, 다가오는 일정)

6. 매칭 엔진

점수 산출 (0~100)

기준 가중치 로직
지역 매칭 30 preferred_regions에 포함 → 30점
주택유형 매칭 10 preferred_types에 포함 → 10점
면적 매칭 15 min_area~max_area 범위 내 주택형 존재 → 15점
가격 매칭 15 max_price 이하 주택형 존재 → 15점
자격 매칭 30 지원 가능 공급유형 수에 비례

자격 매칭 세부

공급유형 판별 조건
일반 1순위 무주택 + 세대주 + 청약통장 가입기간 충족 (투기과열 24개월, 그 외 12개월)
일반 2순위 1순위 미충족 시
특별-신혼부부 is_newlywed + 무주택 + 소득기준
특별-생애최초 is_first_home + 무주택 + 소득기준
특별-다자녀 children_count >= 2 + 무주택
특별-노부모부양 has_dependents + 무주택
특별-청년 age 19~39 + 무주택
특별-신생아 has_newborn + 무주택
  • 1개 유형 → 10점, 2개 → 20점, 3개 이상 → 30점
  • eligible_types: 지원 가능 유형 목록 저장
  • match_reasons: 각 판별 사유 저장

상태 자동 계산

오늘 < receipt_start             → 청약예정
receipt_start ≤ 오늘 ≤ receipt_end → 청약중
receipt_end < 오늘 ≤ winner_date   → 결과발표
오늘 > winner_date                → 완료

매칭 실행 시점

  • 신규 공고 수집 후 자동 실행
  • 프로필 변경 시 POST /matches/refresh로 재계산
  • 매일 00:00 상태 갱신 시 재매칭

7. 인프라 통합

Docker Compose

realestate-lab:
  build: ./realestate-lab
  container_name: realestate-lab
  ports:
    - "18800:8000"
  volumes:
    - ${RUNTIME_PATH:-.}/data:/app/data
  environment:
    - DATA_GO_KR_API_KEY=${DATA_GO_KR_API_KEY}
  restart: unless-stopped

Nginx

location /api/realestate/ {
    proxy_pass http://realestate-lab:8000;
}

APScheduler

시간 Job 설명
매일 09:00 run_collection 5개 API 수집 → 매칭
매일 00:00 update_statuses 날짜 기반 상태 갱신

배포

  • scripts/deploy-nas.shrealestate-lab/ rsync 대상 추가

8. lotto-backend 제거 대상

파일 제거 항목
backend/app/db.py realestate_complexes 테이블 생성, CRUD 함수 5개
backend/app/main.py ComplexCreate/ComplexUpdate 모델, /api/realestate/complexes 라우트 4개

기존 realestate_complexes 테이블 데이터는 마이그레이션 불필요 (스키마 완전 상이).


9. 환경변수

변수 설명 필수
DATA_GO_KR_API_KEY 공공데이터포털 API 키 선택 (미설정 시 수동 등록만 가능)

10. 향후 확장

  • 텔레그램 알림: 신규 매칭 공고 발생 시 텔레그램 봇으로 push (알림 모듈 분리 구조 대비)
  • 경쟁률 조회: 청약 접수 기간 중 경쟁률 실시간 수집
  • 실거래가 비교: 주변 시세와 분양가 비교 분석