글자 크기

5주차 빌드 로그: 채팅 V1 — 거래는 결국 대화다

이번 주에 내가 만든 건 단순히 채팅 기능이 아니다.
앱 안에 “사람과 사람 사이의 길”을 하나 뚫어 둔 것에 가깝다.

마켓이든 동네 앱이든, 결국 마지막은 늘 이 한 문장으로 귀결된다.

“혹시 지금 가능하세요?”
“네, 어디서 볼까요?”

그 대화를 앱 안에서 시작할 수 있게 만드는 것.
그게 이번 5주차의 목표였고, 결론적으로 Chat V1을 완성했다.


이번 주의 목표: “1:1 채팅 방 생성 + 읽음(최소)”

Week 5의 범위는 과감하게 잘랐다.

  • 그룹채팅? 나중에.
  • 첨부파일? 나중에.
  • 알림/푸시? 나중에.

이번엔 딱 이것만:

  1. 1:1 DM 대화방 생성/재사용
  2. ActionCable 기반 실시간 메시지 전송
  3. 읽음 처리 최소(last_read_at)
  4. 게시글 상세에서 DM 바로 시작

“최소 기능”이라 쓰고, 사실은 “서비스가 굴러가기 위한 최소 생존 장치”라고 읽는다.

💡 최소 기능 = 최소 생존 장치.
살아남아야 성장도 한다.

구현 요약: 이번 주에 들어간 것들

1) 라우팅: 대화/메시지 구조 확정

  • conversations#index, conversations#show
  • conversation_messages#create
  • 게시글에서 바로 DM 시작: POST /posts/:id/dmconversations#create_from_post

즉, 사용자는 복잡한 흐름 없이 게시글 → DM 버튼 → 대화방으로 바로 들어간다.

2) DB 설계: 미래 확장 가능하게 “딱 필요한 만큼만”

테이블은 3개로 정리했다.

  • conversations — direct(1:1) 대화의 뼈대, user_a_id / user_b_id 구조
  • conversation_participants — 참가자 연결 + last_read_at (읽음 최소)
  • conversation_messages — 메시지 본문(body), 작성자(user_id)

여기서 포인트는 “완성형 설계”가 아니라
미래에 기능이 붙을 자리를 남겨둔 최소 설계라는 점이다.

3) 모델/로직: “같은 사람끼리 방이 두 개 생기면 망한다”

그래서 핵심은 이것:

  • 같은 두 유저의 direct 대화는 하나만 존재해야 한다
  • find_or_create_direct(user1, user2)재사용 보장
  • unread_count_for(user)로 읽지 않은 메시지 수 계산

이게 없으면 사용자 경험이 바로 무너진다.
채팅은 “있냐 없냐”보다 “헷갈리냐 안 헷갈리냐”가 더 중요하니까.

4) UI: 메시지 버블 + 대화 목록 + 읽음 카운트

  • 대화방: 메시지 버블 UI(내 메시지/상대 메시지 분리)
  • 대화 목록: 마지막 메시지 + 상대방 + unread count

아직 화려하진 않다.
하지만 난 요즘 화려함보다 “정직함”이 더 좋더라.


테스트: 이번 주 가장 큰 수확

이번 주는 기능보다 테스트에서 얻은 게 더 크다.

  • DM 생성/재사용 플로우 테스트
  • 권한 테스트(참가자만 접근 가능)
  • 읽음 처리(last_read_at 업데이트)
  • 메시지 생성 테스트

중간에 Devise/Warden 관련 에러도 터졌고,
partial 경로 문제도 터졌고,
unread count 기대값이 0으로 떨어지는 것도 봤다.

근데 그런 삐끗함 덕분에 확신이 생겼다.

“아, 이 앱은 이제 진짜 서비스의 모양을 갖춰가고 있구나.”


Week 5 최종 완료 체크

  • ✅ DM 생성/재사용 동작
  • ✅ 실시간 메시징 동작(ActionCable/Turbo stream)
  • ✅ 읽음 처리 최소(last_read_at 갱신)
  • ✅ 통합 테스트 통과
  • ✅ 전체 테스트 통과 상태 유지

다음 주(Week 6) 예고: 신뢰/안전 MVP

채팅이 생기면 좋은 일만 생기진 않는다.
오히려 이제부터가 현실이다.

그래서 다음 주는 “성장”이 아니라 “안전장치”다.

  • 신고/차단 최소
  • 레이트리밋(도배/스팸 방지)
  • 관리자 최소 화면(신고 처리)

서비스는 낭만으로만 못 간다.
하지만 낭만을 지키기 위해서라도,
최소한의 질서와 방어선이 필요하다.


끝으로, 오늘의 기록

나는 늦게 시작했다.
그리고 몸도 예전 같지 않다.
그런데도 이 앱을 만드는 이유는 단순하다.

사람들이 서로를 만나는 길을 하나라도 더 정성스럽게 만들고 싶어서.

이번 주, 그 길 위에 “대화”라는 다리를 하나 놓았다.
작지만 단단한 다리.

💡 사람과 사람 사이에 길을 뚫는 일.
그게 이 앱이 하는 일이다.

이제 다음 주는, 그 다리가 무너지지 않도록 난간을 달 차례다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다