Skip to content

[GMSS-98] feat: 시드 문장으로 대화방 제목을 정해 목록에 표시 - #17

Merged
seunghee17 merged 13 commits into
developfrom
feature/conversation-title
Aug 13, 2026
Merged

[GMSS-98] feat: 시드 문장으로 대화방 제목을 정해 목록에 표시#17
seunghee17 merged 13 commits into
developfrom
feature/conversation-title

Conversation

@soyeonLee126

@soyeonLee126 soyeonLee126 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

작업 개요

서버는 대화방을 제목 없이 만들고, 제목은 PATCH /api/conversations/{conversationId}/title 로만 붙습니다.
클라이언트에 그 호출이 없어서 목록·검색의 title 이 전부 null 이었고, 목록 화면도 더미 데이터를 그리고 있었습니다.

첫 발화(시드 문장, 최대 140자)에서 제목을 만들어 방 생성 직후 한 번 지정하고, 목록을 실제 데이터로 바꿉니다.

작업 유형

  • feat: 새 기능
  • fix: 버그 수정
  • refactor: 리팩토링 (동작 변경 없음)
  • build: 빌드/의존성 설정
  • chore: 기타 (문서, 설정 등)
  • test: 테스트 추가/수정

변경 사항

제목 생성 규칙 (ConversationTitlePolicy)

  • 첫 문장을 그대로 제목으로 쓰지 않고, 사실 어절이 있는 문장을 골라 앞머리 군더더기만 걷어냅니다.
  • 붙여 쓴 표현은 접두를 벗겨 판정하되, 벗긴 나머지가 감정어일 때만 군더더기로 봅니다. 그래서 "이직"·"개발자"·"괴롭힘"은 그대로 남습니다.
  • 미검출은 감수하고 오검출을 줄이는 쪽으로 맞췄습니다.

제목 지정 흐름

  • ConversationSession.finishSend() 에서 제목 지정과 요약 압축을 함께 처리합니다.
  • 제목은 첫 발화에서 1회 확정하고, 이어 쓰는 대화나 불러온 대화는 건드리지 않습니다.
  • 제목 요청은 applicationScope 에서 태워 호출자 취소와 분리합니다.
  • 취소로 결과를 못 본 경우에는 세션이 pending 제목을 복구해 다음 뒷정리에서 다시 시도합니다.

목록 화면

  • GET /api/conversations?date= 로 그날 방을 받아 실제 제목을 보여줍니다. 더미 10개를 걷어냈습니다.
  • 제목이 없는 방은 "제목 없는 대화"로 표시합니다.
  • 새 대화는 플로팅 버튼으로 엽니다.

관련 이슈

관련 작업 (Notion)

스크린샷 / 동작 화면

실기기(Galaxy S23) dev-api.gamss.kr 검증 로그입니다.

--> POST  /api/conversations/messages   {"content":"오늘 햄버거 먹고싶은데 기분이 안좋아"}
<-- 200   conversationId=38
--> PATCH /api/conversations/38/title   {"title":"햄버거 먹고싶은데 기분이 안좋아"}
<-- 200   {"id":38,"title":"햄버거 먹고싶은데 기분이 안좋아","status":"ACTIVE"}
시드 제목
오늘 햄버거 먹고싶은데 기분이 안좋아 햄버거 먹고싶은데 기분이 안좋아
이진짜개짜증나 팀장새끼 나 일시켜놓고 지혼자 쏠랑 튀었어 팀장새끼 나 일시켜놓고 지혼자 쏠랑…
오늘 너무 힘들었어. 팀장이 회의에서 아이디어 가로챘어 팀장이 회의에서 아이디어 가로챘어
괴롭힘 신고했어 결국 괴롭힘 신고했어 결국
boss took my idea at the meeting boss took my idea a…

체크리스트

  • base 브랜치가 develop으로 설정되어 있다
  • 로컬 빌드 및 실행을 확인했다
  • 커밋 메시지가 컨벤션(feat:, fix: 등)을 따른다
  • 불필요한 로그/주석/디버그 코드를 제거했다
  • 리뷰어가 이해할 수 있도록 설명을 작성했다

base 는 develop 이 아니라 feature/chat-messaging 입니다.

리뷰 요청 사항

  • 제목 규칙의 오검출: 사실 어절을 잘못 지우는 입력이 보이면 알려주세요.
  • MIN_TITLE_LENGTH(6자) 임계값: "팀장 탓" 같은 짧은 사실이 뒤 문장에 밀릴 수 있어 후속 조정 여지가 있습니다.
  • applicationScope 사용: 제목 요청은 호출자 취소와 분리하고, 취소로 결과를 못 본 경우는 세션이 재시도합니다.
  • 목록 화면: 날짜는 오늘치만 조회하고, 날짜 구분·마지막 메시지·읽음 상태는 넣지 않았습니다.

테스트

  • ConversationTitlePolicyTest 22개
  • ConversationSessionTest 9개
  • UpdateConversationTitleUseCaseTest 5개
  • ConversationRepositoryImplTest 1개
  • ConversationResponseTest 2개
  • ChatRoomRevealTest 6개
  • ./gradlew :domain:test --tests com.gamss.android.domain.conversation.ConversationSessionTest :data:testDebugUnitTest --tests com.gamss.android.data.repository.ConversationRepositoryImplTest 통과

서버는 대화방을 제목 없이 만들고 PATCH /api/conversations/{id}/title 로만 제목이 붙는다.
첫 발화(시드)에서 제목을 만들어 방 생성 직후 한 번 지정하고, 목록을 실제 데이터로 바꾼다.

- ConversationTitlePolicy: 감정 토로가 아니라 무슨 일이 있었는지가 남도록 사실 어절이 있는
  문장을 골라 앞머리 군더더기만 뗀다. 붙여 쓴 표현("이진짜개짜증나")은 접두를 벗겨 판정하되,
  벗긴 나머지가 감정어일 때만 군더더기로 본다("이직"·"괴롭힘"은 그대로 남는다).
- 요약 모델(DiarySummarizer)은 쓰지 않는다. 시드는 140자 이하라 압축할 여지가 적고 짧은
  캐주얼 입력은 요약 모델의 분포 밖이며, 목록에 바로 보여야 해서 추론 지연을 감수할 이유가 없다.
- 제목 지정은 finishSend 로 옮겨 전송 왕복에 매달지 않는다. 화면 이탈로 호출자가 취소돼도
  요청은 완주하도록 applicationScope 에서 태운다.
- 대화방 목록은 GET /api/conversations?date= 로 그날 방을 받아 제목을 보여주고,
  새 대화는 플로팅 버튼으로 연다.
- 목록 조회 날짜를 KST 로 고정한다. LocalDate.now() 는 기기 시간대를 따라
  해외·시간대 변경 기기에서 하루 어긋난 목록을 받는다. Clock 을 주입해 테스트도 가능해진다.
- finishSend 에서 제목 지정과 요약 압축을 병렬로 돌린다. 직렬로 두면 느린 제목 요청이
  압축을 붙들어, 그 사이 보낸 다음 발화가 압축 전 컨텍스트를 싣는다(Orbit 인텐트는 병렬이다).
- 제목 지정의 락 구간을 상태 읽기·쓰기로 좁힌다. HTTP 왕복 전체를 쥐고 있으면 뒷정리끼리
  줄을 선다. pending 을 꺼내면서 비워 겹친 호출이 같은 제목을 두 번 보내지 않게 한다.
- 되돌아오지 않는 실패(권한·삭제된 방)에 매 전송마다 왕복이 붙지 않도록 재시도를 3회로 제한한다.
- 자문하는 의문문이 뒤 문장에 밀리던 문제를 고친다("회사 그만둬야 할까? 진짜 고민된다").
- 목록 첫 로드 전에 "대화가 없어요"가 깜빡이지 않게 isLoading 으로 시작한다.
- 정책 테스트가 어휘가 아니라 규칙을 고정하도록 보강한다. 뮤테이션을 주입해 확인한 결과,
  종전 테스트는 BARE_EMOTIONS 를 통째로 비우거나 구분자를 지워도 전부 통과했다.
팀에 돌릴 배포본이 필요한데, 대화 탭이 BuildConfig.DEBUG 로 가려져 있어 release 로는 보이지 않고
debug 는 340MB 에 디버깅까지 열려 있다.

- local.properties 의 네 값이 모두 있을 때만 릴리즈 키로 서명한다. 없으면 서명 없이 빌드되므로
  키스토어가 없는 환경(CI·다른 개발자)에서도 그대로 돌아간다.
- internal 빌드 타입을 release 기준으로 만든다. isDebuggable 은 끄고, applicationId 는 release 와
  같이 둬서 이미 등록된 릴리즈 키 지문으로 소셜 로그인이 된다. 서버는 dev 를 본다.
- 화면 게이팅을 BuildConfig.DEBUG 에서 떼어 INTERNAL_TOOLS 로 옮긴다. BuildInfo.isDebug 는
  HTTP 로그용으로 남기고, 미노출 화면 여부는 showsInternalTools 로 나눈다.

internal APK 는 172MB 로 debug 의 절반이다(release 기준이라 요약 모델이 빠진다).
@soyeonLee126
soyeonLee126 marked this pull request as ready for review August 9, 2026 13:46
@soyeonLee126 soyeonLee126 changed the title feat: 시드 문장으로 대화방 제목을 정해 목록에 표시 [GMSS-98] feat: 시드 문장으로 대화방 제목을 정해 목록에 표시 Aug 9, 2026
Base automatically changed from feature/chat-messaging to develop August 10, 2026 13:02
Comment thread app/src/main/kotlin/com/gamss/android/app/di/ClockModule.kt Outdated
날짜별 대화방 조회가 기획에서 빠져, 목록을 /api/conversations/incomplete 로 받는다.
하루치만 보던 탓에 어제 쓰다 만 방이 목록에서 빠지고 오늘 종료한 방은 남던 것도 함께 사라진다.
목록이 날짜를 쓰지 않게 되면서 Clock 소비자가 없어져 ClockModule 도 지운다.
문장 분리의 mapNotNull 람다 본문 들여쓰기를 맞추고, 쓰지 않는 import 를 지운다.
ConversationSession 은 한 대화의 순서를 지키는 자리라 의존 수를 줄이지 않고 규칙만 억제한다.

@seunghee17 seunghee17 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다!

@seunghee17
seunghee17 merged commit 4c9b580 into develop Aug 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants