F6. 1:1 채팅
1. 기능명
주최자–낙찰자 1:1 채팅
2. 기능 목적
낙찰 이후 물건이 실제로 전달되게 한다.
- 주최자와 낙찰자가 전달 방법·시점을 논의한다
- 외부 연락처를 교환하지 않고도 거래가 완결된다
채팅의 목적은 전달 논의 하나다. 참여 전 문의나 잡담을 위한 기능이 아니다.
택배냐 직거래냐를 여기서 정한다. 서비스는 둘 중 하나를 강요하지 않는다. 그래서 경매를 열 때 배송지를 묻지 않고 (F1 3.2), 택배로 정해진 경우에만 이 대화에서 주소를 주고받는다. 상단 안내가 그 점을 한 줄로 못박는다:
ⓘ 택배로 보낼지 직접 만날지, 배송지도 여기서 정하세요. ‘{경매명}’ 경매
주소를 앱이 미리 받아두지 않는 이유는, 받아둘 수 있는 것이 주최자 본인의 주소뿐이기 때문이다. 택배에 정작 필요한 것은 낙찰자의 주소이고, 그건 낙찰이 확정된 이 대화에서야 의미가 생긴다.
3. 동작 방식
3.1 대화 상대
채팅은 경매 1건당 주최자와 낙찰자 사이에서만 이루어진다.
| 참여자 | 판정 |
|---|---|
| 주최자 | 경매 등록자 (auction.user_id) |
| 낙찰자 | 낙찰된 사연의 작성자 (F5) |
그 외 누구도 채팅에 참여할 수 없다. 미낙찰 참여자, 방문자, 비회원 모두 해당한다.
3.2 생성 시점
채팅방은 낙찰이 확정된 뒤에 생성된다. 마감 전에는 존재하지 않는다.
경매 마감 → 낙찰자 확정(F5) → 채팅방 생성 → 양쪽에 알림 발송
- 경매 1건당 채팅방 1개다. 상대가 정해져 있으므로 조합을 따질 필요가 없다
- 유찰된 경매에는 채팅방이 생기지 않는다
방 식별에
auction_id하나면 충분하다. 주최자와 낙찰자는 경매 데이터에서 도출되므로 별도 참여자 컬럼이 필요 없다.
3.3 진입
| 진입점 | 동작 |
|---|---|
| 낙찰 알림 | 해당 채팅방으로 이동 |
| 경매 상세 (마감 후) | 주최자·낙찰자에게만 대화하기 버튼 노출 |
| 마이페이지 | 내 경매 / 내 사연에서 낙찰 건 진입 |
채팅 목록 화면(/chat)을 두지 않는다.
방은 낙찰된 경매당 1개뿐이고, 그 경매는 이미 세 곳에서 눈에 띈다 — 알림·경매 상세·마이페이지. 목록을 따로 두면 같은 것을 네 번째로 나열하게 된다.
기존 서비스에는 목록이 있었다. 로그인한 누구나 아무에게나 말을 걸 수 있어 방이 여러 개 쌓였기 때문이다. 채팅을 주최자–낙찰자로 좁힌 순간(3.1) 목록의 존재 이유가 사라졌다. 과한 것은 덜어낸다.
3.4 메시지
| 항목 | 내용 |
|---|---|
| 형식 | 텍스트 · 배송 정보(3.6) 두 가지 |
| 전송 | 실시간 반영 |
| 읽음 처리 | 상대가 방을 열면 읽음으로 표시. 내가 보낸 말풍선 옆에 읽음 / 안읽음 을 모두 적는다 — 읽었을 때만 표시하면 '아직 안 읽음'과 '표시가 없는 것'이 구분되지 않는다. 보낸 사람이 가장 궁금해하는 것이 그 차이다. 읽음은 강조색, 안읽음은 눌러 둔다 |
| 정렬 | 시간순, 최신 메시지가 하단 |
| 알림 | 메시지 도착 시 상대의 알림 목록과 헤더 배지에 반영 (F9). 푸시는 없다 |
3.5 권한 요약
| 관계 | 채팅 |
|---|---|
| 비회원 | - |
| 주최자 | O (낙찰 확정 후) |
| 낙찰자 | O |
| 미낙찰 참여자 | - |
| 방문자 | - |
3.6 배송 정보 보내기
택배로 정해지면 낙찰자의 이름 · 연락처 · 주소가 필요하다. 마이페이지에 저장해 둔 배송지(F12 3.2)에 이미 다 있는데 대화에 손으로 옮겨 적게 하지 않는다.
입력줄 위에 배송 정보 보내기 버튼을 둔다.
버튼을 누른다
→ 배송지가 없으면 등록 화면으로 보내고, 마치면 이 대화로 돌아온다
→ 있으면 보낼 값을 그대로 보여주고 확인을 받는다
→ 확인하면 메시지 한 건으로 들어간다
| 항목 | 내용 |
|---|---|
| 노출 | 낙찰자에게만. 택배에 필요한 것은 받는 쪽 정보다 |
| 확인 | 보낼 값을 그대로 미리 보여준다. 이름·연락처까지 나가고 되돌릴 수 없다 |
| 표시 | 말풍선이 아니라 카드로 그린다. 대화를 올려 다시 찾을 때 한눈에 걸려야 한다 |
| 재전송 | 막지 않는다. 주소가 바뀌면 다시 보낸다 |
자동으로 노출하지 않는 이유 — 낙찰됐다고 집 주소가 주최자에게 저절로 뜨면, 직거래로 만나기로 한 경우에도 주소가 넘어간다. 주소는 되돌릴 수 없는 개인정보라 필요해서 준 것과 그냥 보인 것은 다르다. 직거래면 누르지 않으면 그만이다.
주최자가 배송지를 읽는 것이 아니다. 낙찰자가 자기 정보를 메시지로 복사해 보내는 구조라 addresses 의 "본인만 조회" 정책을 열지 않는다. 값이 메시지에 복사되므로 보낸 시점의 스냅샷이 남는다 — 나중에 배송지를 고쳐도 이미 보낸 정보는 그대로다. 송장을 쓴 시점의 주소가 남아야 한다.
3.7 알려진 한계
마감 전에는 주최자에게 문의할 수단이 없다.
주최자는 경매 등록 시 사연 요청 설명(F1 3.3)에 필요한 정보를 충분히 담아야 한다. 참여자가 궁금한 점을 물을 곳이 없기 때문이다.
참여 전 문의 채널은 이번 범위에 포함하지 않는다. 채팅을 전달 논의로 한정하면 알림 빈도가 낮아지고(F9), 방 관리가 단순해진다.
4. 예외 처리
| 상황 | 처리 |
|---|---|
| 주최자·낙찰자가 아닌 사용자의 진입 | 차단하고 알림 목록으로 이동시킨다. RLS 가 '방이 없음'과 '참여자가 아님'을 구분 불가능하게 막으므로 경매를 특정할 수 없다 |
| 비회원 진입 | 홈으로 이동시키고 로그인을 유도한다 |
| 마감 전 채팅 시도 | 대화하기 버튼을 노출하지 않는다. 방이 존재하지 않으므로 직접 진입도 실패한다 |
| 유찰된 경매 | 채팅방을 만들지 않는다. 대화하기 버튼을 노출하지 않는다 |
| 채팅방 생성 실패 | 낙찰 확정은 롤백하지 않는다. 생성을 재시도하고, 실패가 지속되면 경매 상세 진입 시 생성을 시도한다 |
| 메시지 전송 실패 | 해당 메시지를 전송 실패 상태로 표시하고 재전송을 제공한다. 입력 내용을 지우지 않는다 |
| 실시간 연결 끊김 | 재연결을 시도하고, 재연결 시 누락 메시지를 다시 불러온다. 연결 상태를 화면에 표시한다 |
| 메시지 목록 조회 실패 | 에러 상태와 재시도를 제공한다. 빈 대화로 위장하지 않는다 |
| 존재하지 않는 방 ID로 진입 | 알림 목록으로 이동시킨다 |
| 낙찰 사연이 삭제됨 | 낙찰 사연은 삭제할 수 없다 (F3 3.4). 이 상황은 발생하지 않아야 한다 |
| 대화 중 경매가 삭제됨 | 사연이 있는 경매는 삭제할 수 없다 (F1 3.6). 이 상황은 발생하지 않아야 한다 |
| 빈 메시지 전송 | 전송하지 않는다. 공백만 입력한 경우도 동일하다 |
5. 완료 조건
| # | 조건 |
|---|---|
| 1 | 낙찰 확정 시 채팅방이 자동 생성되고 양쪽에 알림이 발송된다 |
| 2 | 경매 1건당 채팅방이 1개만 존재한다 |
| 3 | 주최자와 낙찰자만 입장할 수 있다. 그 외 접근이 차단된다 |
| 4 | 마감 전·유찰 경매에는 채팅방이 생성되지 않는다 |
| 5 | 채팅방 식별에 auction_id 외의 참여자 컬럼이 필요하지 않다 |
| 6 | 메시지가 실시간으로 도착하고 읽음 상태가 반영된다 |
| 7 | 전송 실패 메시지가 표시되고 재전송할 수 있다 |
| 8 | 채팅방 생성 실패가 낙찰 결과를 되돌리지 않는다 |
| 9 | 낙찰자만 배송 정보를 보낼 수 있고, 보내기 전에 보낼 값을 확인한다 (3.6) |
| 10 | 배송지가 없으면 등록 화면으로 안내되고, 마치면 이 대화로 복귀한다 |