| name | ipzitalk-presale-compare-card |
| description | 분양단지를 한 장 카드로 정리한다. 단지 1개면 개요 카드(분양가·평당가·공급세대·주택형·입주월· 공급유형·위치), 2개 이상이면 같은 전용타입 기준 축별 비교(우위 표시·이격 경고·위치 지도)를 낸다. "분양단지 정보", "이 분양단지 개요", "OO 분양가/세대수", "이 청약 단지 요약", "분양단지 카드", "분양단지 비교", "이 단지 어때", "A 단지 vs B 단지", "A랑 B 비교", "어디가 나아", "배틀카드" 등의 표현이 있으면 이 스킬을 사용한다.
|
| version | 1.0.2 |
| license | proprietary |
분양단지 비교 카드 (ipzitalk-presale-compare-card)
tier: L2
분양단지를 개요·비교 카드 한 장으로 정리한다. 단지 1개면 개요 카드, 2개 이상이면 같은 전용타입 기준 축별 비교.
종합 우열은 단정하지 않고 축별 우위만 표시한다(가중치=사용자 몫).
※ 데이터 = 청약홈 분양정보 적재분만. 분양가 = 주택형별 최고가(평균 아님). 비교는 대상 단지 전부 적재돼 있어야 한다.
입력 (지점형 — 단지명/주소, 비교면 2개 이상)
| 파라미터 | 필수 | 기본 | 설명 |
|---|
query(자유형) | ✅ | - | 분양단지명 또는 주소. 개요면 1개, 비교면 2개 이상 |
exclusive_area_sqm | ✕ | 84(비교) | 비교 전용타입(같은 타입끼리). 개요는 특정 타입만 볼 때 |
지점형 = 대상 단지를 특정. 단지명이 자연스럽고 주소도 가능(지역명·코드만으로는 특정 불가 → 단지명 추가 요청).
단지명이 여러 공고에 매칭되면 후보 제시 후 선택(자동 확정 금지).
비교는 대상 단지가 각각 적재돼 있어야 한다. 미적재면 "적재 안 됨" 명시(추정 금지).
워크플로우 (검증됨 · 2026-07-09)
- 입력 해소 — 각 단지: 단지명→주소검색(주거시설 우선)→좌표, 주소→지오코딩→좌표. 후보 다수면 선택(자동확정 금지).
- 대상 조회 — 각 단지 공고 + 주택형 포함. 단지명 매칭이 표기차로 0건이면 좌표+반경으로 재조회.
- 분기
- 단지 1개(개요): 개요 추출(공급위치·시공/시행·공고일·입주월·상한제·원문) → 주택형 정리(전용/공급면적·최고분양가(억)·평당가·일반+특공 세대) → 최고/최저·총 일반/특공 집계.
- 단지 2개+(비교): 각 단지에서 같은 전용타입(예 84㎡) 대표 주택형(최고 평당가) 추출 → 축별 비교(84 최고분양가·84 평당가·총세대·입주월·상한제·시공사·공고일). 우위: 가격/평당가=낮을수록·세대=클수록·입주=빠를수록 유리, 상한제·시공사=중립. A·B 이격(haversine) 크면 "단순 평당가 비교 부적절" 경고.
- 지도 — 개요=단일 마커, 비교=A(파랑)·B(빨강) 마커 fitBounds.
- 렌더 — 고정 템플릿
templates/result.html에 ipzi-data JSON 주입. listings 길이로 개요/비교를 자동 분기한다.
공정성 규칙 (비교 모드 핵심)
- 같은 전용타입 기준(84 vs 84). 다른 평형 비교 금지.
- 🚨 공통 타입이 없으면 최대 공통 전용타입으로 내린다. 실측: 잠실 르엘은 최대 전용 74㎡라 래미안(84·104㎡)과 84 비교가 불가능했다. → 공통 74㎡로 비교.
- 공통 타입이 하나도 없으면 비교하지 않는다. 그 사실을 화면에 쓴다.
- 생활권 위계가 다르면(이격 큼) 경고 — 단순 평당가 비교 부적절.
- 종합 우열 단정 금지 → 축별 우위만 표시, "가중치는 사용자 몫".
- 평당가는 공급면적 기준 = 최고분양가 ÷ (공급면적 ÷ 3.3058).
🚨 공고 시점이 다르면 가격 축에 우위를 표시하지 않는다 (실측 2026-07-09)
기존 규칙은 "가격/평당가 = 낮을수록 유리" 였다. 이것만으로는 틀린다.
잠실 르엘 공고 2025-08-19 74㎡ 최고 18.74억 공급면적 평당 6,168만원
잠실 래미안아이파크 공고 2024-10-11 74㎡ 최고 17.96억 공급면적 평당 5,624만원
↑ 10개월 차이
0.78억 격차가 단지 우열인지 시점 차이인지 구분할 수 없다. 그 사이 시세·정책이 분양가에 반영된다.
두 단지는 신천동 340m 이격이라 위치 위계 차이는 작다. 그런데도 평당가가 9.7% 벌어졌다.
- 공고일 차이가 6개월 이상이면 가격·평당가 축의
winner 를 null 로 둔다. 색칠하지 않는다.
- 대신 시점 차이를 경고 문구로 명시한다. 값은 그대로 나열한다.
- 세대수·입주월·상한제·시공사처럼 시점과 무관하게 확정되는 축만 우위를 표시한다.
ipzi-data JSON 계약 — chips 는 객체다
렌더 JS 가 c.text || c 로 문자열도 받지만, 채우는 쪽은 항상 객체로 넣는다.
chips: [ { text: "분양가상한제", cap: true }, { text: "216세대", cap: false } ]
cap: true 인 칩만 강조 스타일을 받는다. 문자열을 넣으면 cap 이 없어 강조가 사라진다.
재사용 로직 (메커니즘)
- 입력 해소: 단지명/주소 → 대상 좌표. 각 단지마다 적용. 후보 다수면 선택.
- 개요 추출 로직을 비교 모드의 A·B 각각에 재사용(단일=개요 부품, 복수=그 부품 ×N).
- 출처 라벨 매핑: 화면에는 사용자 표시 문구(분양공고=「청약홈」, 주택형=「청약홈」, 지도=「네이버 지도」). 내부 테이블명 HTML 노출 금지.
섹션마다 출처를 작게 단다
데이터 블록 하단에 .src 한 줄. 도구·API 이름은 쓰지 않는다. 사용자가 아는 기관명만.
| 블록 | 출처 표기 |
|---|
| 단지 개요·세대수·준공·주차·연차 | 공동주택관리정보시스템(K-apt) |
| 매매·전세·평당가·거래량 | 국토교통부 실거래가 |
| 학교·교통·생활·상권 등 장소 | 카카오맵 |
| 분양공고·분양가·주택형·입주월 | 청약홈 |
| 지도 (장소 마커) | 네이버 지도 · 카카오맵 |
| 지도 (분양공고 마커) | 네이버 지도 · 청약홈 |
- 🚨 출처 문자열은
ipzi-data JSON으로 받지 않고 템플릿 마크업에 직접 박는다.
어느 블록이 어디서 왔는지는 실행마다 달라지지 않는다. 데이터로 받으면 채우는 걸 잊거나 틀리게 쓸 여지만 생긴다.
- 🚨 한 블록에 두 출처가 섞이면 병기한다. 예:
세대수·주차 — 공동주택관리정보시스템(K-apt) · 위치 — 카카오맵.
하나로 뭉뚱그리면 어느 숫자가 어디서 왔는지 사용자가 알 수 없다.
- 🚨 쓰지 않은 기관을 출처로 적지 않는다. 우리가 부르는 곳은 위 다섯 곳뿐이다.
- 히어로·유의사항·푸터에는 달지 않는다. 데이터 블록에만.
디자인 정본 (템플릿에 인라인)
산출물 HTML은 스킬 폴더 밖 문서에 의존하지 않는다. 규칙은 templates/result.html에 인라인돼 있다.
- 하나의 템플릿이 두 모드를 처리한다:
ipzi-data.listings 길이 1이면 개요, 2 이상이면 축별 비교표. 0이면 두 모드 모두 숨긴다.
- CDN·외부 폰트·이모지 금지. 아이콘은
<symbol> 인라인 + <use> 참조로 self-contained. ICONS 화이트리스트에 없는 id는 렌더하지 않고 console.warn.
- 라이트/다크 양쪽:
prefers-color-scheme + :root[data-theme] 모두 대응.
- 토큰만 사용:
--bg --card --ink --sub --line --chip --g --y --o --r --x --brand(+ -s 배경 변형)·비교 팀색 --a --b · --mono.
★·☆는 활자 기호이며 이모지가 아니다.
- 결측 셀은
정보없음(0으로 채우지 않는다). 값 추정 금지.
- 분양가·평당가는 주택형별 최고가 기준 — priceNote를 항상 표기한다.
- 🚨 반경 눈금 마커를 넣지 않는다. 예전엔
fitBounds가 반경 원을 무시해 원이 잘리는 걸 막으려고
정북·남·동·서에 회색 더미 마커 4개를 심었다. 사용자에게는 정체를 알 수 없는 점으로 보여 혼란만 준다.
원이 잘리더라도 마커는 실제 장소만 찍는다. (근본 해결은 render.ts가 원을 bounds에 포함하도록 고치는 것 — 발견사항 6번)
- 지도:
map.url이 null이면 지도 패널을 숨긴다. 지도 링크는 발급 후 7일간 유효하므로 캡션에 유효기간을 적는다. 비교 모드는 이격 경고를 지도 하단에 표기.
- 실행마다 바뀌는 것은
ipzi-data 비실행 JSON 블록 하나뿐 — 마크업·CSS·렌더 JS는 고정.
출력 포맷
- 채팅(먼저)
- 개요: 단지명·최고분양가·총세대(일반/특공)·입주월·주택형 수 + 주택형별 분양가 md 표.
- 비교: A/B 84 분양가·평당가·세대·입주 + 축별 우위 요약(A N개·B N개).
- HTML(선택)
- 개요: 히어로(칩: DB기준·상한제) → 요약 4박스 → 공고 개요 → 주택형별 분양가 표 → 위치 지도 → 출처·hedge 푸터.
- 비교: 히어로 → VS 헤더(A 파랑·B 빨강) → 축별 비교표(우위 셀 색상) → 위치 지도(이격 경고) → 출처·hedge 푸터.
- 레이아웃 기준:
templates/result.html
HTML 산출물 계약 🚨
- 렌더 데이터는
result.json에 저장하고, 사용자 전달 HTML은 고정 정본 templates/result.html의 ipzi-data 블록만 교체해 만든다. 새 HTML을 작성하거나 마크업·CSS·렌더 JS를 수정하지 않는다.
- 단지 1개면 셸 허용 환경에서 스킬 기준
../../scripts/html_artifact_contract.mjs를 --file-name "<단지명>_분양카드"와 함께 사용하고 <단지명>_분양카드.html로 저장한다.
- 단지 2개면
<A>_<B>_분양비교.html, 3개 이상이면 <첫단지>외N곳_분양비교.html을 사용한다. shell-free 환경에서도 같은 이름으로 저장하고 교체 전후의 fixed template region이 원본과 같은지 비교한다.
- 내부 파일
result.json·audit.json은 고정 이름을 유지하되, 사용자 전달 HTML을 result.html이나 index.html이라는 고정 이름으로 내지 않는다.
필수 단서 · 금지 표현
- 필수: 최고가 기준 · 공급면적 평당가 · 상한제 여부 · 청약홈 적재 기준일 · 경쟁률/일정 미포함. (비교) 같은 전용타입 기준 · A·B 이격 거리 · "가중치는 사용자 몫".
- 금지: 최고가를 평균가처럼 · 적정분양가 판단(=분양가 검증 스킬) · 종합 우열 단정 · 다른 평형 비교 · 내부 테이블명 HTML 노출.
엣지 · 실패 처리
| 상황 | 처리 |
|---|
| 여러 공고 매칭 | 후보 나열 후 선택 |
| 주택형 0건 | 공고 개요만, 분양가 "-" |
| 미측위(좌표 없음) | 좌표 보완 시도, 실패 시 지도 생략 |
| (비교) 한쪽 미적재 | "○ 단지 적재 안 됨" 명시, 비교 불가 |
| (비교) 한쪽 84㎡ 없음 | 공통 전용타입으로 대체 또는 유보 |
| (비교) A·B 이격 큼 | 경고 배너 + 생활권 위계 차이 명시 |
검증된 사항 (조회 2026-07-09)
- 개요(풍무역 푸르지오 더 마크): 주택형 5개(74A/74B/84A/84B/84C). 최고 7.10억 · 최저 6.33억 · 총 1,524세대(일반 524·특공 1,000) · 입주 2028-11 · 상한제 O. 평당가(공급면적) 74A 2,120 · 84A 2,094 · 84C 2,109만/평.
- 비교(푸르지오 84C vs 롯데캐슬 시그니처 84A): A 최고 7.10억·2,109만/평·1,524세대·2028-11·상한제 O / B 7.84억·2,274만/평·720세대·2028-07·상한제 X. 축별 우위 A 3개(분양가·평당가·세대)·B 1개(입주)·중립 3개. 이격 1,059m(같은 풍무역세권 → 비교 적정).
- 단일 마커 / VS 헤더·우위 색상 셀·2마커 지도 브라우저 렌더 확인.