Skip to content

#49 #50 #51 #52 #53 - 채팅 채널 메시지 기능 구현 (목록 조회·텍스트/파일 전송·기본 채널 시딩) - #199

Merged
yunkihong-dev merged 5 commits into
mainfrom
feat/chat
Jun 27, 2026
Merged

#49 #50 #51 #52 #53 - 채팅 채널 메시지 기능 구현 (목록 조회·텍스트/파일 전송·기본 채널 시딩)#199
yunkihong-dev merged 5 commits into
mainfrom
feat/chat

Conversation

@yunkihong-dev

@yunkihong-dev yunkihong-dev commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

closes #49 #50 #51 #52 #53

작업 내용

  • 채팅 채널 메시지 도메인(Message)·인프라·서비스·API 추가 ([CHAT-001] 채널 목록 조회 #49 채널 목록 조회 위에 이어짐)
  • Message 엔티티 추가 — channel/sender FK, content(TEXT), MessageType(TEXT/FILE), createdAt
  • MessageRepository(페이징) 도메인 인터페이스 + Spring Data/JPA 어댑터(포트-어댑터)
  • 메시지 목록 조회 GET /api/v1/channels/{channelId}/messages?page=0&size=50
  • 최신순(createdAt DESC) 기본 정렬, MessageResponse[] 반환
  • 채널 미존재 시 CHANNEL_NOT_FOUND
  • 텍스트 메시지 전송 POST /api/v1/channels/{channelId}/messages (201 Created)
  • MessageCreateRequest(content, type), sender = 현재 멤버(@AuthenticationPrincipal)
  • type 미지정 시 TEXT로 저장
  • 파일 첨부 메시지 전송 — 같은 경로를 multipart/form-data로 분기
  • MessageFile 엔티티 + Message.files(@onetomany, cascade) + addFile
  • MultipartFile 업로드는 drive 모듈 StorageService(MinIO) 재사용, type=FILE 저장
  • 첨부 없으면 MESSAGE_FILE_REQUIRED, MessageResponse에 files(MessageFileResponse[]) 포함
  • 기본 채널 자동 생성 — ChannelSeeder(ApplicationRunner)
  • 기동 시 General(GENERAL) + 팀별 4개(DEV/DESIGN/MARKETING/PRODUCT, TEAM) 멱등 생성
  • 전체 멤버를 General 채널에 참여 (멱등)
  • ChannelMember 엔티티 + 리포지토리, ChannelRepository.findByName 추가
  • Flyway 마이그레이션 추가
  • V25__create_message.sql (channel/sender FK, (channel_id, created_at) 인덱스)
  • V26__create_message_file.sql (message FK, message_id 인덱스)
  • V27__create_channel_member.sql (channel/member 유니크 제약)
  • ErrorCode에 CHANNEL_NOT_FOUND, MESSAGE_FILE_REQUIRED 추가

체크리스트

  • 테스트 작성 (Red)
  • 기능 구현 (Green)
  • 리팩터링 완료
  • 테스트 전체 통과

정책 결정

  • 마이그레이션 버전: 이슈에는 V10__create_channel.sql로 명시됐으나 V10이 이미 선점되어 채널 테이블([CHAT-001] 채널 목록 조회 #49)은 V24, 메시지/파일/멤버는 V25~V27로 작성
  • 메시지 응답은 페이지 메타데이터(totalElements 등) 없이 MessageResponse[]만 반환 — 이슈 명세 및 프론트 배열 계약에 맞춤
  • 텍스트/파일 전송은 동일 엔드포인트를 content-type으로 분기(JSON vs multipart) — 프론트의 type 기반 호출과 호환
  • 파일 저장은 신규 스토리지 추상화를 만들지 않고 drive 모듈의 MinIO StorageService 빈을 재사용
  • 기본 채널 시딩은 별도 데이터 마이그레이션 대신 ApplicationRunner로 처리하고, findByName/existsByChannelIdAndMemberId로 멱등 보장

체크리스트

  • 테스트 작성 (Red)
  • 기능 구현 (Green)
  • DB 마이그레이션 추가
  • 대상 테스트 통과
  • 전체 테스트 통과

검증

  • ./gradlew test --tests "com.yanus.attendance.chat.*" — chat 모듈 단위 테스트(ChannelService/MessageService/ChannelSeeder) 통과
  • ./gradlew compileJava compileTestJava — 이슈 단계별 컴파일 통과
  • ./gradlew test — 전체 테스트 BUILD SUCCESSFUL (AttendanceApplicationTests.contextLoads() 포함, 신규 엔티티 4종 + ChannelSeeder 기동을 Testcontainers 스키마에서 검증)
  • 프론트 영향
  • 채널 목록: GET /api/v1/channels 응답에 type(GENERAL/TEAM/DIRECT) 포함
  • 메시지 목록: GET /api/v1/channels/{channelId}/messages?page=0&size=50 — 최신순 배열, 각 항목에 senderId/senderName/content/type/files/createdAt
  • 텍스트 전송: POST .../messages JSON 바디 { "content": "...", "type": "TEXT" }
  • 파일 전송: 같은 경로에 multipart/form-data로 content(선택) + files(필수) 전송, 응답 type=FILE & files[] 포함
  • 기본 채널(General + DEV/DESIGN/MARKETING/PRODUCT)은 서버 기동 시 자동 생성되어 별도 생성 요청 불필요

yunkihong-dev and others added 5 commits June 27, 2026 18:16
- Channel 엔티티 추가 (ChannelType: GENERAL/TEAM/DIRECT)
- ChannelRepository(도메인) + ChannelJpaRepository(인프라) 구현
- ChannelService.findAll → ChannelResponse 목록 반환
- GET /api/v1/channels 엔드포인트 추가
- Flyway 마이그레이션 create_channel 추가 (V10은 선점되어 V24 사용)
- ChannelService 단위 테스트 및 FakeChannelRepository 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Message 엔티티 추가 (channel/sender FK, content, MessageType, createdAt)
- MessageRepository(페이징) 도메인 + Spring Data/JPA 어댑터 구현
- MessageService.getMessages(channelId, Pageable) → MessageResponse[] (채널 미존재 시 CHANNEL_NOT_FOUND)
- GET /api/v1/channels/{channelId}/messages?page=0&size=50 (최신순 기본 정렬)
- Flyway V25__create_message.sql (channel/sender FK, channel_id+created_at 인덱스)
- ErrorCode CHANNEL_NOT_FOUND 추가, MessageService 단위 테스트 + FakeMessageRepository

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- MessageCreateRequest DTO 추가 (content, type)
- MessageService.sendMessage(channelId, senderId, content, type): sender = 현재 멤버(@AuthenticationPrincipal), type 미지정 시 TEXT
- POST /api/v1/channels/{channelId}/messages (201 Created)
- 채널/멤버 미존재 시 각각 CHANNEL_NOT_FOUND / MEMBER_NOT_FOUND
- 메시지 전송 단위 테스트 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- MessageFile 엔티티 추가, Message에 files(@onetomany, cascade) + addFile 추가
- MessageService.sendFileMessage: MultipartFile 업로드(StorageService 재사용) 후 type=FILE 메시지로 저장
- POST /api/v1/channels/{channelId}/messages (multipart/form-data, content+files)
- MessageResponse에 files(MessageFileResponse[]) 포함
- 첨부 파일 없으면 MESSAGE_FILE_REQUIRED
- Flyway V26__create_message_file.sql, 파일 메시지 테스트 + FakeStorageService

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ChannelMember 엔티티 + 리포지토리 추가 (channel/member 유니크 제약)
- ChannelSeeder(ApplicationRunner): 기동 시 General(GENERAL) + 팀별 4개(DEV/DESIGN/MARKETING/PRODUCT, TEAM) 멱등 생성, 전체 멤버를 General에 참여
- ChannelRepository.findByName 추가 (멱등 시딩용)
- Flyway V27__create_channel_member.sql
- ChannelSeeder 단위 테스트 + FakeChannelMemberRepository

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yunkihong-dev yunkihong-dev changed the title Feat/chat #49 #50 #51 #52 #53 - 채팅 채널 메시지 기능 구현 (목록 조회·텍스트/파일 전송·기본 채널 시딩) Jun 27, 2026
@yunkihong-dev
yunkihong-dev merged commit e8ea205 into main Jun 27, 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.

[CHAT-001] 채널 목록 조회

1 participant