Skip to content

feat(chat): 메시지를 그것을 만든 태스크에 잇는다 — taskId 저장 + 종류 배치 규칙 명문화 - #315

Merged
dldnsgkr merged 1 commit into
developfrom
unhak/chat-message-task-id
Sep 8, 2026
Merged

feat(chat): 메시지를 그것을 만든 태스크에 잇는다 — taskId 저장 + 종류 배치 규칙 명문화#315
dldnsgkr merged 1 commit into
developfrom
unhak/chat-message-task-id

Conversation

@dldnsgkr

@dldnsgkr dldnsgkr commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

FE(dvely-fe-55)가 kind 를 붙이다 발견한 것. GET /conversations/{id}/messagestaskId 를 전부 null 로 내려준다.

왜 null 이었나

컬럼이 없었다. taskIdPOST 응답에만 실려 나갔다 — 방금 제출한 태스크 id 를 메모리에서 얹어 주는 것이라 저장되지 않는다. 조회 DTO 매핑 누락이 아니라 데이터가 없는 것이었다.

그래서 화면은 "이 줄이 어느 작업의 것인가" 를 알 수 없다:

  • 결과 줄에서 그 작업의 변경 내역(GET /api/v1/changes)으로 넘어가기 — 불가
  • 실패 줄에서 그 작업만 재시도 — 불가
  • 되묻기 답변 ↔ 카드 정확한 짝짓기 — 불가 (FE 는 "가장 마지막 것" 휴리스틱으로 우회 중)

무엇을

  • V59: chat_messages.task_id + (chat_session_id, task_id) 인덱스. 대화 단위로 읽고 태스크로 거르는 패턴이라 복합 인덱스
  • appendAssistanttaskId 인자 추가. BE 서술 줄 26곳 전부에 실었다(미전달 0곳 스크립트 확인)
  • 사용자 발화에도 싣는다. 그러려면 taskId 가 먼저 있어야 해서 ChatCommandService 에서 createPending 을 메시지 저장보다 앞으로 옮겼다 — 같은 트랜잭션이라 뒤가 실패하면 PENDING 태스크도 함께 롤백된다
  • ChatQueryService 가 저장된 값을 읽는다

종류 배치 규칙을 enum 에 남긴다

FE 리뷰에서 나온 것이다. 빌드 실패 후 자동 수정 승인을 요청하는 줄을 내가 실패 무게로 바꾸려 했는데, 그러면 화면이 빨갛게 칠하고 사용자는 되돌릴 수 없이 끝난 것으로 읽어 대화를 접는다 — 실제로는 한 번 누르면 이어지는 자리다.

기준은 "무슨 일이 일어났는가" 가 아니라 "사용자가 지금 무엇을 해야 하는가" 이고, 그것이 화면의 무게 구분과 같은 질문에 답하기 때문에 종류가 늘어도 배치가 흔들리지 않는다:

종류 기준 화면 무게
눌러야 할 것 기본
읽지 않아도 되는 것 흐리게
끝나버린 것 빨강

실패라는 사실은 본문이 말하고("프로젝트 빌드가 완료되지 않았습니다"), 종류는 다음 행동을 말한다. 둘을 같은 채널로 보내면 겹친다.

규칙이 코드에 없어서 내가 잘못 붙일 뻔했으므로 ChatMessageKind javadoc 에 적었다.

검증

기존 검증 34곳을 taskId 까지 고정하도록 갱신했다. 전체 1329개 통과.

머지 후 FE 는 "마지막 하나" 휴리스틱을 정확한 짝 매칭으로 바꿀 수 있다.

🤖 Generated with Claude Code

https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93

여태 taskId 는 POST /conversations/{id}/messages 응답에만 실려 나갔다. 방금 제출한 태스크
id 를 메모리에서 얹어 주는 것이라 저장되지 않았고, 목록 조회(GET)에서는 전부 null 이었다.
그래서 화면은 "이 줄이 어느 작업의 것인가" 를 알 수 없다 — 결과 줄에서 그 작업의 변경
내역으로 넘어가거나 실패 줄에서 그 작업만 재시도하는 것이 불가능하고, FE 는 "가장 마지막
것" 휴리스틱으로 우회하고 있었다.

- V59: chat_messages.task_id + (chat_session_id, task_id) 인덱스. 대화 단위로 읽고 태스크로
  거르는 패턴이라 복합 인덱스로 둔다.
- appendAssistant 에 taskId 인자 추가. BE 가 쓰는 서술 줄 26곳 전부에 실었다(미전달 0곳 확인).
- 사용자 발화에도 싣는다. 그러려면 taskId 가 먼저 있어야 해서 ChatCommandService 에서
  createPending 을 메시지 저장보다 앞으로 옮겼다 — 같은 트랜잭션이라 뒤가 실패하면 PENDING
  태스크도 함께 롤백된다.
- ChatQueryService 가 저장된 값을 읽는다. 그 자리에 있던 "과거 조회는 항상 null" 주석도 갱신.

## 종류 배치 규칙을 enum 에 남긴다

FE 리뷰에서 나온 것이다. 빌드 실패 후 자동 수정 승인을 요청하는 줄을 내가 실패 무게로
바꾸려 했는데, 그러면 화면이 빨갛게 칠하고 사용자는 되돌릴 수 없이 끝난 것으로 읽어 대화를
접는다 — 실제로는 한 번 누르면 이어지는 자리다.

기준은 "무슨 일이 일어났는가" 가 아니라 <b>"사용자가 지금 무엇을 해야 하는가"</b> 이고, 그것이
화면의 무게 구분(눌러야 할 것/읽지 않아도 되는 것/끝나버린 것)과 같은 질문에 답하기 때문에
종류가 늘어도 배치가 흔들리지 않는다. 실패라는 사실은 본문이 말하고 종류는 다음 행동을
말한다 — 둘을 같은 채널로 보내면 겹친다.

규칙이 코드에 없어서 내가 잘못 붙일 뻔했으므로 ChatMessageKind javadoc 에 적었다.

검증: 기존 검증 34곳을 taskId 까지 고정하도록 갱신, 전체 1329개 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93
@dldnsgkr
dldnsgkr merged commit b22a8a6 into develop Sep 8, 2026
1 check 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.

1 participant