Conversation
* style: GrammarConversationService 코드 포맷팅
* style: FeedbackResponse 코드 포맷팅
* style: SessionReportResponse 코드 포맷팅
* style: SpeakingError 코드 포맷팅
* style: SpeakingErrorType 코드 포맷팅
* style: OPIcException 코드 포맷팅
* style: OPIcAnswer 코드 포맷팅
* style: OPIcQuestion 코드 포맷팅
* style: OPIcSession 코드 포맷팅
* style: OPIcRepository 코드 포맷팅
* style: FeedbackService 코드 포맷팅
* style: TranscribeProxyService 코드 포맷팅
* style: VocabularyConfig 코드 포맷팅
* style: DailyStudyCommandService 코드 포맷팅
* style: TestCommandService 코드 포맷팅
* style: TestService 코드 포맷팅
* style: CommonErrorCodeSpec 코드 포맷팅
* style: JsonUtilSpec 코드 포맷팅
* style: BadgeTypeSpec 코드 포맷팅
* style: ChattingErrorCodeSpec 코드 포맷팅
* style: GrammarLevelSpec 코드 포맷팅
* style: GrammarErrorCodeSpec 코드 포맷팅
* style: VocabularyErrorCodeSpec 코드 포맷팅
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
## 변경 사항
### GSI1SK 포맷 변경
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
### 지원 쿼리 패턴
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
### 파일 수정
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
### 마이그레이션
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* fix : 오타 수정
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* Release: 캐치마인드 게임 분리, AI 회화 연습, CI/CD 파이프라인 (#469)
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
## 변경 사항
### GSI1SK 포맷 변경
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
### 지원 쿼리 패턴
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
### 파일 수정
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
### 마이그레이션
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
---------
Co-authored-by: hyein Heo <128613248+hye-inA@users.noreply.github.com>
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: add CORS headers to API Gateway error responses (#479)
API Gateway의 인증 실패 등 에러 응답에 CORS 헤더가 누락되어
CloudFront를 통한 프론트엔드 요청이 차단되는 문제 수정
- UNAUTHORIZED (401) 응답에 CORS 헤더 추가
- ACCESS_DENIED (403) 응답에 CORS 헤더 추가
- DEFAULT_4XX/5XX 응답에 CORS 헤더 추가
- EXPIRED_TOKEN 응답에 CORS 헤더 추가
* feat(news): 뉴스 도메인 기반 구조 구축 (#385)
- NewsCategory, QuizType enum 추가
- NewsKey 상수 클래스 추가
- NewsErrorCode 예외 클래스 추가
- NewsArticle, KeywordInfo, QuizQuestion 모델 추가
- NewsArticleRepository CRUD 구현
- NewsTable DynamoDB 테이블 정의
- CORS GatewayResponses 설정 추가
* feat(news): 뉴스 수집 파이프라인 구현 (#386)
- NewsApiClient: NewsAPI 연동 서비스
- RssFeedParser: RSS 피드 파싱 (BBC, VOA, NPR)
- NewsDuplicateChecker: URL 기반 중복 필터링
- NewsCollectorService: 수집 오케스트레이션
- NewsCollectionHandler: Lambda 핸들러
- EventBridge 스케줄러: 매일 18시 KST 실행
* refactor(news): NewsAPI 제거, RSS만 사용
- NewsApiClient 삭제
- SSM Parameter 의존성 제거
- RSS 소스당 7개씩 수집 (BBC, VOA, NPR = 약 21개/일)
* feat(news): AI 뉴스 분석 시스템 구현 (#387)
- NewsAnalysisService: AI 분석 통합 서비스
- Bedrock: CEFR 난이도 분석 (A1~C2)
- Bedrock: 3줄 요약 + 퀴즈 3문제 생성
- Comprehend: 핵심 키워드 추출
- NewsCollectorService: 수집 시 자동 분석 연동
- GSI1/GSI2 키 자동 설정 (레벨별, 카테고리별 조회)
* feat(news): 뉴스 학습 API 구현 (#388)
- NewsQueryService: 뉴스 조회 서비스
- NewsHandler: API 핸들러
- GET /news - 목록 조회 (level, category 필터)
- GET /news/today - 오늘의 뉴스
- GET /news/recommended - 내 레벨 맞춤 추천
- GET /news/{articleId} - 상세 조회 (조회수 증가)
- template.yaml: NewsFunction Lambda 추가
* feat(news): 뉴스 학습 부가 기능 구현 (#389)
- 읽기 완료 기록 API (POST /news/{articleId}/read)
- 북마크 토글 API (POST /news/{articleId}/bookmark)
- 북마크 목록 조회 API (GET /news/bookmarks)
- 학습 통계 조회 API (GET /news/stats)
- TTS 오디오 URL 조회 API (GET /news/{articleId}/audio)
- UserNewsRecord 모델 추가
- UserNewsRepository 추가
- NewsLearningService 추가
* feat(news): 복합 퀴즈 시스템 구현 (#471)
- 퀴즈 조회 API (GET /news/{articleId}/quiz)
- 퀴즈 제출 API (POST /news/{articleId}/quiz)
- 퀴즈 기록 조회 API (GET /news/quiz/history)
- NewsQuizResult 모델 추가
- QuizAnswerResult 모델 추가
- NewsQuizRepository 추가
- NewsQuizService 추가
* feat(news): 단어 수집 & Vocabulary 연동 구현 (#472)
- 단어 수집 API (POST /news/{articleId}/words)
- 수집 단어 목록 API (GET /news/words)
- 단어 상세 조회 API (GET /news/{articleId}/words/{word})
- 단어 삭제 API (DELETE /news/{articleId}/words/{word})
- Vocabulary 연동 API (POST /news/words/{word}/sync)
- NewsWordCollect 모델 추가
- NewsWordRepository 추가
- NewsWordService 추가
* feat: add multi-environment deployment support (dev/test/prod)
* fix: update buildspec.yml to deploy prod environment with parameter overrides
* feat(news): 뉴스 도메인 기반 구조 구축 (#385)
- NewsCategory, QuizType enum 추가
- NewsKey 상수 클래스 추가
- NewsErrorCode 예외 클래스 추가
- NewsArticle, KeywordInfo, QuizQuestion 모델 추가
- NewsArticleRepository CRUD 구현
- NewsTable DynamoDB 테이블 정의
- CORS GatewayResponses 설정 추가
* feat(news): 뉴스 수집 파이프라인 구현 (#386)
- NewsApiClient: NewsAPI 연동 서비스
- RssFeedParser: RSS 피드 파싱 (BBC, VOA, NPR)
- NewsDuplicateChecker: URL 기반 중복 필터링
- NewsCollectorService: 수집 오케스트레이션
- NewsCollectionHandler: Lambda 핸들러
- EventBridge 스케줄러: 매일 18시 KST 실행
* refactor(news): NewsAPI 제거, RSS만 사용
- NewsApiClient 삭제
- SSM Parameter 의존성 제거
- RSS 소스당 7개씩 수집 (BBC, VOA, NPR = 약 21개/일)
* feat(news): AI 뉴스 분석 시스템 구현 (#387)
- NewsAnalysisService: AI 분석 통합 서비스
- Bedrock: CEFR 난이도 분석 (A1~C2)
- Bedrock: 3줄 요약 + 퀴즈 3문제 생성
- Comprehend: 핵심 키워드 추출
- NewsCollectorService: 수집 시 자동 분석 연동
- GSI1/GSI2 키 자동 설정 (레벨별, 카테고리별 조회)
* feat(news): 뉴스 학습 API 구현 (#388)
- NewsQueryService: 뉴스 조회 서비스
- NewsHandler: API 핸들러
- GET /news - 목록 조회 (level, category 필터)
- GET /news/today - 오늘의 뉴스
- GET /news/recommended - 내 레벨 맞춤 추천
- GET /news/{articleId} - 상세 조회 (조회수 증가)
- template.yaml: NewsFunction Lambda 추가
* feat(news): 뉴스 학습 부가 기능 구현 (#389)
- 읽기 완료 기록 API (POST /news/{articleId}/read)
- 북마크 토글 API (POST /news/{articleId}/bookmark)
- 북마크 목록 조회 API (GET /news/bookmarks)
- 학습 통계 조회 API (GET /news/stats)
- TTS 오디오 URL 조회 API (GET /news/{articleId}/audio)
- UserNewsRecord 모델 추가
- UserNewsRepository 추가
- NewsLearningService 추가
* feat(news): 복합 퀴즈 시스템 구현 (#471)
- 퀴즈 조회 API (GET /news/{articleId}/quiz)
- 퀴즈 제출 API (POST /news/{articleId}/quiz)
- 퀴즈 기록 조회 API (GET /news/quiz/history)
- NewsQuizResult 모델 추가
- QuizAnswerResult 모델 추가
- NewsQuizRepository 추가
- NewsQuizService 추가
* feat(news): 단어 수집 & Vocabulary 연동 구현 (#472)
- 단어 수집 API (POST /news/{articleId}/words)
- 수집 단어 목록 API (GET /news/words)
- 단어 상세 조회 API (GET /news/{articleId}/words/{word})
- 단어 삭제 API (DELETE /news/{articleId}/words/{word})
- Vocabulary 연동 API (POST /news/words/{word}/sync)
- NewsWordCollect 모델 추가
- NewsWordRepository 추가
- NewsWordService 추가
* feat: add multi-environment deployment support (dev/test/prod)
* fix: update buildspec.yml to deploy prod environment with parameter overrides
* refactor : AI 말하기 Websocket 구현 -> REST API 구현으로 리팩토링 (#490)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: revert buildspec.yml to build-only for CloudFormation deploy stage
* fix: revert buildspec.yml to build-only for CloudFormation deploy stage
* fix: update all API Gateway StageName to use Environment parameter
* fix: correct VocabularyTable and ContentBucket references in NewsFunction
* fix: correct VocabularyTable and ContentBucket references in NewsFunction
* fix: add stack name prefix to GameScheduleGroup and daily-stats schedule to avoid conflicts
* fix: add stack name prefix to GameScheduleGroup and daily-stats schedule to avoid conflicts
* feat: add support for existing Cognito User Pool reuse across environments
* fix: add conditional Cognito ARN reference in API Gateway Authorizer
* fix: remove Cognito resources completely, use existing Cognito only
* fix: remove Cognito resources completely, use existing Cognito only
* feat : speaking rest API 람다 함수 추가
* feat: add S3 bucket resource and fix environment-specific endpoints
- Add ContentBucket S3 resource for content storage
- Replace hardcoded /dev with ${Environment} in all WebSocket endpoints
- Update Output URLs to use dynamic environment stage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add stack name prefix to news-collection schedule name
Prevent EventBridge rule name conflicts across environments
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add X-Requested-With and Accept headers to CORS config
Enable additional headers for CloudFront CORS compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use environment variable for S3 bucket URLs
Replace hardcoded bucket name with BUCKET_NAME env var for multi-env support:
- PreSignUpHandler: dynamic default profile URL
- PostConfirmationHandler: dynamic default profile URL
- UserService: dynamic default profile URL
- BadgeType: dynamic badge image base URL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: disable authorizer for CORS preflight requests
Add AddDefaultAuthorizerToCorsPreflight: false to prevent
Cognito Authorizer from blocking OPTIONS requests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat : speaking REST API 람다 함수 추가 (#491)
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* fix : 오타 수정
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: add CORS headers to API Gateway error responses (#479)
API Gateway의 인증 실패 등 에러 응답에 CORS 헤더가 누락되어
CloudFront를 통한 프론트엔드 요청이 차단되는 문제 수정
- UNAUTHORIZED (401) 응답에 CORS 헤더 추가
- ACCESS_DENIED (403) 응답에 CORS 헤더 추가
- DEFAULT_4XX/5XX 응답에 CORS 헤더 추가
- EXPIRED_TOKEN 응답에 CORS 헤더 추가
* feat : speaking rest API 람다 함수 추가
---------
Co-authored-by: ddingjoo <ddingsha9@teambind.co.kr>
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feature : test 벡엔드 서버에 AI 말하기 연습 기능 배포 (#492)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat : handleChat 메서드 JsonNull 체크 푸가
* feature : handleChat 메서드 JsonNull 체크 추가 (#493)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feat : handleChat 메서드 JsonNull 체크 푸가
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat(news): 뉴스 학습 배지 시스템 구현 (#473)
- 14개 뉴스 관련 배지 추가 (읽기, 퀴즈, 단어수집, 연속학습, 마스터)
- UserStats에 뉴스 통계 필드 추가
- 6개 뉴스 배지 Strategy 클래스 생성
- 뉴스 읽기/퀴즈/단어수집 시 통계 업데이트 및 배지 체크 연동
* fix: add PATCH method to CORS AllowMethods
* test: BadgeType 개수 테스트 수정 (15 -> 29)
* fix: CORS PATCH 메서드 추가
* docs: 뉴스 기능 프론트엔드 연동 가이드 작성
* fix: NewsCollectionFunction에 Bedrock, Comprehend 권한 추가
* fix: add null check for collectWord request body
- Add INVALID_REQUEST error code to NewsErrorCode
- Check body and word field before accessing in collectWord()
- Prevents NullPointerException when request body is malformed
* feat: enhance stats API and bookmark response for frontend
- Add DAILY stats update for news read/quiz/word collection
- Add /stats/dashboard endpoint with frontend-requested format
- today: wordsLearned, newsRead, quizzesTaken, wordsTotal
- overall: totalWordsLearned, totalNewsRead, averageAccuracy, streaks
- weeklyProgress: last 7 days with date/wordsLearned/newsRead
- Add news-related fields to all stats API responses
- Fix bookmark API to include full article details (title, summary, etc.)
* feat: add category classification to news AI analysis
- Add category field to AnalysisResult record
- Update Bedrock prompt to classify articles into categories
(WORLD, POLITICS, BUSINESS, TECH, SCIENCE, HEALTH, SPORTS, ENTERTAINMENT, LIFESTYLE)
- Parse and set category from AI response
- Set GSI2 (CATEGORY#) index when category is available
* fix: add /stats/dashboard endpoint to template.yaml
* fix: filter by ARTICLE# prefix in findById to avoid returning UserNewsRecord
* docs: add News API troubleshooting guide
* feat: add Cognito authorizer to News API and enhance keyword extraction
- Set CognitoAuthorizer for all News API endpoints in template.yaml
- Update Bedrock AI to extract keywords with meanings and examples
- Add fallback to Comprehend for keyword extraction when Bedrock fails
- Modify KeywordInfo model to include example field
- Adjust AI prompt to include keyword extraction with examples
- Update AnalysisResult to store keywords and parse them from AI response
* Revert "Merge branch 'test' into prod"
This reverts commit c1a958eac6799d5838a76e4078ae304bcdb62278, reversing
changes made to a6662e0cfc46c6e12f20a89f0df285ff282160bc.
* feat: enhance bookmark and reading status tracking for News API
- Add bookmark and reading status to individual article responses
- Include bookmark status in paginated news responses
- Modify `KeywordInfo` to support Korean translations (`meaningKo`)
- Update AI prompts to extract Korean meanings for keywords
* refactor : session_id가 null 체크 추가
* fix : sessionId NullPointerException 에러 수정 (#496)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feat : handleChat 메서드 JsonNull 체크 푸가
* refactor : session_id가 null 체크 추가
* feat : template 환경변수 리펙토링
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat: enhance bookmark and reading status tracking for News API
- Add bookmark and reading status to individual article responses
- Include bookmark status in paginated news responses
- Modify `KeywordInfo` to support Korean translations (`meaningKo`)
- Update AI prompts to extract Korean meanings for keywords
* feat: add category filtering to UserWord API with enhanced query logic
- Introduce `category` filtering to `getUserWords` API
- Update WordCategory enums to include "news" category
- Apply category filter after enrichment with word info
- Adjust query limits for bookmarked and incorrect words queries
* feat: add default value for ExistingCognitoClientId in template.yaml
- Set default to an empty string to ensure compatibility with templates using this parameter without explicitly specifying a value.
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* refactor: format code with consistent indentation and spacing
- Apply consistent formatting to improve code readability across multiple files
- Adjust indentation, spacing, and alignment in model classes, DTOs, and repository methods
* fix: filter by ARTICLE# prefix in findById to avoid returning bookmark records
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feature : Speaking Table & Function template.yaml 파일에 추가 (#513)
* fix: BadgeRepository 클라이언트 초기화 패턴 통일
- 개별 DynamoDbEnhancedClient 생성 대신 AwsClients.dynamoDbEnhanced() 싱글톤 사용
- 다른 Repository들과 동일한 패턴 적용
- 불필요한 import 제거
Closes #396
* feat: EnvConfig 유틸리티 추가 및 환경 변수 검증 적용
환경 변수 미설정 시 명확한 에러 메시지를 제공하는 EnvConfig 유틸리티를 추가하고,
기존 System.getenv 호출을 EnvConfig.getRequired/getOrDefault로 대체함.
- EnvConfig: getRequired, getOrDefault, getIntOrDefault, getLongOrDefault 메서드 제공
- Lambda Cold Start 시점에 환경 변수 누락을 조기 감지
- 기존 Config 클래스(WebSocketConfig, RoomTokenConfig) EnvConfig 사용으로 통일
Closes #403
* refactor: TestService submitTest 메서드 책임 분리
submitTest 메서드를 단일 책임 원칙에 맞게 리팩토링:
- gradeAnswers(): 답안 채점 및 결과 집계
- isAnswerCorrect(): 단일 답안 정답 여부 판단
- buildResultItem(): 결과 항목 생성
- saveTestResult(): 테스트 결과 저장
- GradingResult record: 채점 결과 캡슐화
TestService와 TestCommandService 모두 동일하게 적용
Closes #404
* refactor: 하드코딩된 설정값 환경 변수로 외부화
각 도메인별 Config 클래스를 생성하여 하드코딩된 값들을 환경 변수로 설정 가능하게 변경.
기본값이 있어 환경 변수 미설정 시에도 기존 동작 유지.
## 새로 추가된 Config 클래스
- GrammarConfig: SESSION_TTL_DAYS, MAX_HISTORY_MESSAGES, MAX_TOKENS 등
- GameConfig: TOTAL_ROUNDS, ROUND_TIME_LIMIT, QUICK_GUESS_THRESHOLD_MS
- VocabularyConfig: NEW_WORDS_COUNT, REVIEW_WORDS_COUNT, 상태 전이 임계값 등
## 지원하는 환경 변수
- GRAMMAR_SESSION_TTL_DAYS, GRAMMAR_MAX_HISTORY_MESSAGES, GRAMMAR_MAX_TOKENS
- GAME_TOTAL_ROUNDS, GAME_ROUND_TIME_LIMIT, GAME_QUICK_GUESS_THRESHOLD_MS
- VOCAB_NEW_WORDS_COUNT, VOCAB_REVIEW_WORDS_COUNT
- VOCAB_TRANSITION_TO_REVIEWING, VOCAB_TRANSITION_TO_MASTERED
Closes #406
* test: StudyLevel enum 단위 테스트 추가
* test: Difficulty enum 단위 테스트 추가
* test: StudyConfig 단위 테스트 추가
* test: EnvConfig 단위 테스트 추가
* test: PaginatedResult 단위 테스트 추가
* test: JsonUtil 단위 테스트 추가
* test: CursorUtil 단위 테스트 추가
* test: CommonErrorCode 단위 테스트 추가
* test: CommonException 단위 테스트 추가
* test: BadgeType enum 단위 테스트 추가
* test: BadgeKey 상수 단위 테스트 추가
* test: WordStatus enum 단위 테스트 추가
* test: TestType enum 단위 테스트 추가
* test: VocabularyConfig 단위 테스트 추가
* test: VocabKey 상수 단위 테스트 추가
* test: VocabularyErrorCode 단위 테스트 추가
* test: VocabularyException 단위 테스트 추가
* test: SpacedRepetitionContext 단위 테스트 추가
* test: GrammarLevel enum 단위 테스트 추가
* test: GrammarConfig 단위 테스트 추가
* test: GrammarErrorCode 단위 테스트 추가
* test: GrammarException 단위 테스트 추가
* test: GameStatus enum 단위 테스트 추가
* test: GameConfig 단위 테스트 추가
* test: ChattingErrorCode 단위 테스트 추가
* test: ChattingException 단위 테스트 추가
* fix: OPIc FeedbackResponse.java 문법 오류 수정
* style: AwsClients 코드 포맷팅
* style: EnvConfig 코드 포맷팅
* style: RoomTokenConfig 코드 포맷팅
* style: WebSocketConfig 코드 포맷팅
* style: JsonUtil 코드 포맷팅
* style: GameConfig 코드 포맷팅
* style: GrammarConfig 코드 포맷팅
* style: GrammarKey 코드 포맷팅
* style: GrammarErrorCode 코드 포맷팅
* style: GrammarException 코드 포맷팅
* style: BedrockGrammarCheckFactory 코드 포맷팅
* style: GrammarConversationService 코드 포맷팅
* style: FeedbackResponse 코드 포맷팅
* style: SessionReportResponse 코드 포맷팅
* style: SpeakingError 코드 포맷팅
* style: SpeakingErrorType 코드 포맷팅
* style: OPIcException 코드 포맷팅
* style: OPIcAnswer 코드 포맷팅
* style: OPIcQuestion 코드 포맷팅
* style: OPIcSession 코드 포맷팅
* style: OPIcRepository 코드 포맷팅
* style: FeedbackService 코드 포맷팅
* style: TranscribeProxyService 코드 포맷팅
* style: VocabularyConfig 코드 포맷팅
* style: DailyStudyCommandService 코드 포맷팅
* style: TestCommandService 코드 포맷팅
* style: TestService 코드 포맷팅
* style: CommonErrorCodeSpec 코드 포맷팅
* style: JsonUtilSpec 코드 포맷팅
* style: BadgeTypeSpec 코드 포맷팅
* style: ChattingErrorCodeSpec 코드 포맷팅
* style: GrammarLevelSpec 코드 포맷팅
* style: GrammarErrorCodeSpec 코드 포맷팅
* style: VocabularyErrorCodeSpec 코드 포맷팅
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환…
* style: SessionReportResponse 코드 포맷팅
* style: SpeakingError 코드 포맷팅
* style: SpeakingErrorType 코드 포맷팅
* style: OPIcException 코드 포맷팅
* style: OPIcAnswer 코드 포맷팅
* style: OPIcQuestion 코드 포맷팅
* style: OPIcSession 코드 포맷팅
* style: OPIcRepository 코드 포맷팅
* style: FeedbackService 코드 포맷팅
* style: TranscribeProxyService 코드 포맷팅
* style: VocabularyConfig 코드 포맷팅
* style: DailyStudyCommandService 코드 포맷팅
* style: TestCommandService 코드 포맷팅
* style: TestService 코드 포맷팅
* style: CommonErrorCodeSpec 코드 포맷팅
* style: JsonUtilSpec 코드 포맷팅
* style: BadgeTypeSpec 코드 포맷팅
* style: ChattingErrorCodeSpec 코드 포맷팅
* style: GrammarLevelSpec 코드 포맷팅
* style: GrammarErrorCodeSpec 코드 포맷팅
* style: VocabularyErrorCodeSpec 코드 포맷팅
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
## 변경 사항
### GSI1SK 포맷 변경
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
### 지원 쿼리 패턴
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
### 파일 수정
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
### 마이그레이션
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* fix : 오타 수정
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* Release: 캐치마인드 게임 분리, AI 회화 연습, CI/CD 파이프라인 (#469)
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
## 변경 사항
### GSI1SK 포맷 변경
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
### 지원 쿼리 패턴
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
### 파일 수정
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
### 마이그레이션
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
---------
Co-authored-by: hyein Heo <128613248+hye-inA@users.noreply.github.com>
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: add CORS headers to API Gateway error responses (#479)
API Gateway의 인증 실패 등 에러 응답에 CORS 헤더가 누락되어
CloudFront를 통한 프론트엔드 요청이 차단되는 문제 수정
- UNAUTHORIZED (401) 응답에 CORS 헤더 추가
- ACCESS_DENIED (403) 응답에 CORS 헤더 추가
- DEFAULT_4XX/5XX 응답에 CORS 헤더 추가
- EXPIRED_TOKEN 응답에 CORS 헤더 추가
* feat(news): 뉴스 도메인 기반 구조 구축 (#385)
- NewsCategory, QuizType enum 추가
- NewsKey 상수 클래스 추가
- NewsErrorCode 예외 클래스 추가
- NewsArticle, KeywordInfo, QuizQuestion 모델 추가
- NewsArticleRepository CRUD 구현
- NewsTable DynamoDB 테이블 정의
- CORS GatewayResponses 설정 추가
* feat(news): 뉴스 수집 파이프라인 구현 (#386)
- NewsApiClient: NewsAPI 연동 서비스
- RssFeedParser: RSS 피드 파싱 (BBC, VOA, NPR)
- NewsDuplicateChecker: URL 기반 중복 필터링
- NewsCollectorService: 수집 오케스트레이션
- NewsCollectionHandler: Lambda 핸들러
- EventBridge 스케줄러: 매일 18시 KST 실행
* refactor(news): NewsAPI 제거, RSS만 사용
- NewsApiClient 삭제
- SSM Parameter 의존성 제거
- RSS 소스당 7개씩 수집 (BBC, VOA, NPR = 약 21개/일)
* feat(news): AI 뉴스 분석 시스템 구현 (#387)
- NewsAnalysisService: AI 분석 통합 서비스
- Bedrock: CEFR 난이도 분석 (A1~C2)
- Bedrock: 3줄 요약 + 퀴즈 3문제 생성
- Comprehend: 핵심 키워드 추출
- NewsCollectorService: 수집 시 자동 분석 연동
- GSI1/GSI2 키 자동 설정 (레벨별, 카테고리별 조회)
* feat(news): 뉴스 학습 API 구현 (#388)
- NewsQueryService: 뉴스 조회 서비스
- NewsHandler: API 핸들러
- GET /news - 목록 조회 (level, category 필터)
- GET /news/today - 오늘의 뉴스
- GET /news/recommended - 내 레벨 맞춤 추천
- GET /news/{articleId} - 상세 조회 (조회수 증가)
- template.yaml: NewsFunction Lambda 추가
* feat(news): 뉴스 학습 부가 기능 구현 (#389)
- 읽기 완료 기록 API (POST /news/{articleId}/read)
- 북마크 토글 API (POST /news/{articleId}/bookmark)
- 북마크 목록 조회 API (GET /news/bookmarks)
- 학습 통계 조회 API (GET /news/stats)
- TTS 오디오 URL 조회 API (GET /news/{articleId}/audio)
- UserNewsRecord 모델 추가
- UserNewsRepository 추가
- NewsLearningService 추가
* feat(news): 복합 퀴즈 시스템 구현 (#471)
- 퀴즈 조회 API (GET /news/{articleId}/quiz)
- 퀴즈 제출 API (POST /news/{articleId}/quiz)
- 퀴즈 기록 조회 API (GET /news/quiz/history)
- NewsQuizResult 모델 추가
- QuizAnswerResult 모델 추가
- NewsQuizRepository 추가
- NewsQuizService 추가
* feat(news): 단어 수집 & Vocabulary 연동 구현 (#472)
- 단어 수집 API (POST /news/{articleId}/words)
- 수집 단어 목록 API (GET /news/words)
- 단어 상세 조회 API (GET /news/{articleId}/words/{word})
- 단어 삭제 API (DELETE /news/{articleId}/words/{word})
- Vocabulary 연동 API (POST /news/words/{word}/sync)
- NewsWordCollect 모델 추가
- NewsWordRepository 추가
- NewsWordService 추가
* feat: add multi-environment deployment support (dev/test/prod)
* fix: update buildspec.yml to deploy prod environment with parameter overrides
* feat(news): 뉴스 도메인 기반 구조 구축 (#385)
- NewsCategory, QuizType enum 추가
- NewsKey 상수 클래스 추가
- NewsErrorCode 예외 클래스 추가
- NewsArticle, KeywordInfo, QuizQuestion 모델 추가
- NewsArticleRepository CRUD 구현
- NewsTable DynamoDB 테이블 정의
- CORS GatewayResponses 설정 추가
* feat(news): 뉴스 수집 파이프라인 구현 (#386)
- NewsApiClient: NewsAPI 연동 서비스
- RssFeedParser: RSS 피드 파싱 (BBC, VOA, NPR)
- NewsDuplicateChecker: URL 기반 중복 필터링
- NewsCollectorService: 수집 오케스트레이션
- NewsCollectionHandler: Lambda 핸들러
- EventBridge 스케줄러: 매일 18시 KST 실행
* refactor(news): NewsAPI 제거, RSS만 사용
- NewsApiClient 삭제
- SSM Parameter 의존성 제거
- RSS 소스당 7개씩 수집 (BBC, VOA, NPR = 약 21개/일)
* feat(news): AI 뉴스 분석 시스템 구현 (#387)
- NewsAnalysisService: AI 분석 통합 서비스
- Bedrock: CEFR 난이도 분석 (A1~C2)
- Bedrock: 3줄 요약 + 퀴즈 3문제 생성
- Comprehend: 핵심 키워드 추출
- NewsCollectorService: 수집 시 자동 분석 연동
- GSI1/GSI2 키 자동 설정 (레벨별, 카테고리별 조회)
* feat(news): 뉴스 학습 API 구현 (#388)
- NewsQueryService: 뉴스 조회 서비스
- NewsHandler: API 핸들러
- GET /news - 목록 조회 (level, category 필터)
- GET /news/today - 오늘의 뉴스
- GET /news/recommended - 내 레벨 맞춤 추천
- GET /news/{articleId} - 상세 조회 (조회수 증가)
- template.yaml: NewsFunction Lambda 추가
* feat(news): 뉴스 학습 부가 기능 구현 (#389)
- 읽기 완료 기록 API (POST /news/{articleId}/read)
- 북마크 토글 API (POST /news/{articleId}/bookmark)
- 북마크 목록 조회 API (GET /news/bookmarks)
- 학습 통계 조회 API (GET /news/stats)
- TTS 오디오 URL 조회 API (GET /news/{articleId}/audio)
- UserNewsRecord 모델 추가
- UserNewsRepository 추가
- NewsLearningService 추가
* feat(news): 복합 퀴즈 시스템 구현 (#471)
- 퀴즈 조회 API (GET /news/{articleId}/quiz)
- 퀴즈 제출 API (POST /news/{articleId}/quiz)
- 퀴즈 기록 조회 API (GET /news/quiz/history)
- NewsQuizResult 모델 추가
- QuizAnswerResult 모델 추가
- NewsQuizRepository 추가
- NewsQuizService 추가
* feat(news): 단어 수집 & Vocabulary 연동 구현 (#472)
- 단어 수집 API (POST /news/{articleId}/words)
- 수집 단어 목록 API (GET /news/words)
- 단어 상세 조회 API (GET /news/{articleId}/words/{word})
- 단어 삭제 API (DELETE /news/{articleId}/words/{word})
- Vocabulary 연동 API (POST /news/words/{word}/sync)
- NewsWordCollect 모델 추가
- NewsWordRepository 추가
- NewsWordService 추가
* feat: add multi-environment deployment support (dev/test/prod)
* fix: update buildspec.yml to deploy prod environment with parameter overrides
* refactor : AI 말하기 Websocket 구현 -> REST API 구현으로 리팩토링 (#490)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: revert buildspec.yml to build-only for CloudFormation deploy stage
* fix: revert buildspec.yml to build-only for CloudFormation deploy stage
* fix: update all API Gateway StageName to use Environment parameter
* fix: correct VocabularyTable and ContentBucket references in NewsFunction
* fix: correct VocabularyTable and ContentBucket references in NewsFunction
* fix: add stack name prefix to GameScheduleGroup and daily-stats schedule to avoid conflicts
* fix: add stack name prefix to GameScheduleGroup and daily-stats schedule to avoid conflicts
* feat: add support for existing Cognito User Pool reuse across environments
* fix: add conditional Cognito ARN reference in API Gateway Authorizer
* fix: remove Cognito resources completely, use existing Cognito only
* fix: remove Cognito resources completely, use existing Cognito only
* feat : speaking rest API 람다 함수 추가
* feat: add S3 bucket resource and fix environment-specific endpoints
- Add ContentBucket S3 resource for content storage
- Replace hardcoded /dev with ${Environment} in all WebSocket endpoints
- Update Output URLs to use dynamic environment stage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add stack name prefix to news-collection schedule name
Prevent EventBridge rule name conflicts across environments
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add X-Requested-With and Accept headers to CORS config
Enable additional headers for CloudFront CORS compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use environment variable for S3 bucket URLs
Replace hardcoded bucket name with BUCKET_NAME env var for multi-env support:
- PreSignUpHandler: dynamic default profile URL
- PostConfirmationHandler: dynamic default profile URL
- UserService: dynamic default profile URL
- BadgeType: dynamic badge image base URL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: disable authorizer for CORS preflight requests
Add AddDefaultAuthorizerToCorsPreflight: false to prevent
Cognito Authorizer from blocking OPTIONS requests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat : speaking REST API 람다 함수 추가 (#491)
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketDisconnectFunction에 WEBSOCKET_ENDPOINT 추가
- execute-api:ManageConnections 권한 추가
* fix: Grammar WebSocket Lambda 환경 변수 및 권한 추가
- GrammarStreamingConnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- GrammarStreamingDisconnectFunction에 WEBSOCKET_ENDPOINT 환경 변수 추가
- 두 함수에 execute-api:ManageConnections 권한 추가
* feat: GSI1SK 확장성 있는 재설계 및 DB 레벨 필터링
- 기존: {level}#{createdAt}
- 신규: {type}#{gameType}#{status}#{level}#{createdAt}
- 전체 방: GSI1PK = "ROOMS"
- 게임방만: begins_with(GSI1SK, "GAME#")
- 캐치마인드만: begins_with(GSI1SK, "GAME#CATCHMIND#")
- 대기중 캐치마인드: begins_with(GSI1SK, "GAME#CATCHMIND#WAITING#")
- ChatRoomCommandService.java: 방 생성 시 새 GSI1SK 포맷 적용
- ChatRoomRepository.java: findByFilters() 메서드 추가, updateStatus() 메서드 추가
- ChatRoomQueryService.java: 메모리 필터링 제거, DB 레벨 필터링으로 변경
- GameService.java: 게임 시작/종료 시 방 상태 업데이트 (GSI1SK 포함)
- scripts/migrate-gsi1sk.sh: 기존 데이터 마이그레이션 스크립트
- 37개 기존 방 마이그레이션 완료
* fix: increase stats query limit to 100 days
- Adjust maximum allowable limit for recent stats query from 30 to 100 days to support extended data range responses.
* feat: improve game round and connection management logic
- Added handling for game round timeout (`ROUND_TIMEOUT`) in WebSocketMessageHandler.
- Enhanced game start broadcast to include `currentWord` for the drawer only.
- Updated ConnectionRepository to remove duplicate user connections in the same room.
- Added `currentWordEnglish` to GameSession for better answer verification.
- Normalized ChatRoom levels to match database storage format.
- Updated template.yaml to include DynamoDBReadPolicy for VocabTable.
* refactor: 코드 정리 및 미사용 클래스 제거 (#459)
* refactor: remove unused WebSocketResponseUtil
* refactor: add AutoCloseable to WebSocketBroadcaster
* refactor: remove unused TestService
* refactor: remove unused WordService
* refactor: remove unused DailyStudyService
* refactor: remove unused UserWordService
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* style: remove p tag from javadoc
* fix: resolve N+1 query in StatsService
* refactor(all): DI 패턴 및 전략 패턴 적용 (#461)
- Repository, Service, Handler에 DI 생성자 추가 (테스트 용이성)
- BadgeService에 Strategy 패턴 적용 (뱃지 조건 검증 로직 분리)
* refactor: relocate and restructure seed data files
- Moved `question-homes.json` and `words.json` from subdirectories to `seed` folder.
- Updated file paths for better organization and clarity.
* chore: seed 데이터 폴더 구조 정리
* feat: add CI/CD pipeline configuration for CodePipeline
* fix: add SNS topic policy and DependsOn for notification rule
* fix: correct paths in buildspec.yml for CodeBuild
* fix: remove hardcoded JAVA_HOME, use runtime default
* fix: add gradle wrapper for CI/CD build
* fix: use single line sam package command with hardcoded bucket
* fix: use existing stack name group2-englishstudy-chatting
* fix: add missing WEBSOCKET_ENDPOINT env var to WebSocket connect functions
* docs: update FRONTEND-API-GUIDE with new RoomType/RoomStatus structure
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: update WebSocketDisconnectHandler to use GameSession model
- Remove references to deleted ChatRoom game fields
- Use GameSessionRepository to finish active game sessions
- Use ChatRoomRepository.updateStatus() for room state management
* perf: optimize CI/CD build time
- Add pip cache for SAM CLI dependencies
- Enable Gradle parallel builds and build cache
- Add SAM build cache (.aws-sam)
- Use sam build --parallel --cached
- Skip SAM CLI install if already cached
- Remove unnecessary 'clean' to leverage cache
* feat: add custom CodeBuild Docker image with pre-installed tools
- Dockerfile with Java 21 + SAM CLI + Gradle pre-installed
- build-and-push.sh script for ECR deployment
- Updated buildspec.yml for custom image (removes SAM CLI install)
- Expected build time reduction: ~30-40 seconds
* feature : AI 영어 회화 연습 기능 (#468)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix: remove typo in SpeakingConnectionRepository
* fix : 오타 수정
* chore: trigger build test with custom Docker image
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* chore: remove unnecessary newlines and whitespace across WebSocket handlers and related classes
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* fix: add CORS headers to API Gateway error responses (#479)
API Gateway의 인증 실패 등 에러 응답에 CORS 헤더가 누락되어
CloudFront를 통한 프론트엔드 요청이 차단되는 문제 수정
- UNAUTHORIZED (401) 응답에 CORS 헤더 추가
- ACCESS_DENIED (403) 응답에 CORS 헤더 추가
- DEFAULT_4XX/5XX 응답에 CORS 헤더 추가
- EXPIRED_TOKEN 응답에 CORS 헤더 추가
* feat : speaking rest API 람다 함수 추가
---------
Co-authored-by: ddingjoo <ddingsha9@teambind.co.kr>
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feature : test 벡엔드 서버에 AI 말하기 연습 기능 배포 (#492)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat : handleChat 메서드 JsonNull 체크 푸가
* feature : handleChat 메서드 JsonNull 체크 추가 (#493)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feat : handleChat 메서드 JsonNull 체크 푸가
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat(news): 뉴스 학습 배지 시스템 구현 (#473)
- 14개 뉴스 관련 배지 추가 (읽기, 퀴즈, 단어수집, 연속학습, 마스터)
- UserStats에 뉴스 통계 필드 추가
- 6개 뉴스 배지 Strategy 클래스 생성
- 뉴스 읽기/퀴즈/단어수집 시 통계 업데이트 및 배지 체크 연동
* fix: add PATCH method to CORS AllowMethods
* test: BadgeType 개수 테스트 수정 (15 -> 29)
* fix: CORS PATCH 메서드 추가
* docs: 뉴스 기능 프론트엔드 연동 가이드 작성
* fix: NewsCollectionFunction에 Bedrock, Comprehend 권한 추가
* fix: add null check for collectWord request body
- Add INVALID_REQUEST error code to NewsErrorCode
- Check body and word field before accessing in collectWord()
- Prevents NullPointerException when request body is malformed
* feat: enhance stats API and bookmark response for frontend
- Add DAILY stats update for news read/quiz/word collection
- Add /stats/dashboard endpoint with frontend-requested format
- today: wordsLearned, newsRead, quizzesTaken, wordsTotal
- overall: totalWordsLearned, totalNewsRead, averageAccuracy, streaks
- weeklyProgress: last 7 days with date/wordsLearned/newsRead
- Add news-related fields to all stats API responses
- Fix bookmark API to include full article details (title, summary, etc.)
* feat: add category classification to news AI analysis
- Add category field to AnalysisResult record
- Update Bedrock prompt to classify articles into categories
(WORLD, POLITICS, BUSINESS, TECH, SCIENCE, HEALTH, SPORTS, ENTERTAINMENT, LIFESTYLE)
- Parse and set category from AI response
- Set GSI2 (CATEGORY#) index when category is available
* fix: add /stats/dashboard endpoint to template.yaml
* fix: filter by ARTICLE# prefix in findById to avoid returning UserNewsRecord
* docs: add News API troubleshooting guide
* feat: add Cognito authorizer to News API and enhance keyword extraction
- Set CognitoAuthorizer for all News API endpoints in template.yaml
- Update Bedrock AI to extract keywords with meanings and examples
- Add fallback to Comprehend for keyword extraction when Bedrock fails
- Modify KeywordInfo model to include example field
- Adjust AI prompt to include keyword extraction with examples
- Update AnalysisResult to store keywords and parse them from AI response
* Revert "Merge branch 'test' into prod"
This reverts commit c1a958eac6799d5838a76e4078ae304bcdb62278, reversing
changes made to a6662e0cfc46c6e12f20a89f0df285ff282160bc.
* feat: enhance bookmark and reading status tracking for News API
- Add bookmark and reading status to individual article responses
- Include bookmark status in paginated news responses
- Modify `KeywordInfo` to support Korean translations (`meaningKo`)
- Update AI prompts to extract Korean meanings for keywords
* refactor : session_id가 null 체크 추가
* fix : sessionId NullPointerException 에러 수정 (#496)
* feat : WebSocket Connect, Disconnect 핸들러 & SpeakingConnecion 모델 구현
* feat : WebSocket 메시지 처리 handler, service 구현
* feat : WebSocket 연결 정보 Repository 구현
* fix : 오타 수정
* refactor : websocket -> rest api 전환
* feat : speaking handler REST로 교체
* feat : speaking 관련 dto 생성
* refacotor : 기존 service 코드 로직 재사용 및 repository 리펙토링
* feat : speaking rest API 람다 함수 추가
* refactor : speaking service 재사용
* refactor : AI 영어 회화 연습 코드 리팩토링
* feat : handleChat 메서드 JsonNull 체크 푸가
* refactor : session_id가 null 체크 추가
* feat : template 환경변수 리펙토링
---------
Co-authored-by: DDING JOO <ddingsha9@teambind.co.kr>
* feat: enhance bookmark and reading status tracking for News API
- Add bookmark and reading status to individual article responses
- Include bookmark status in paginated news responses
- Modify `KeywordInfo` to support Korean translations (`meaningKo`)
- Update AI prompts to extract Korean meanings for keywords
* feat: add category filtering to UserWord API with enhanced query logic
- Introduce `category` filtering to `getUserWords` API
- Update WordCategory enums to include "news" category
- Apply category filter after enrichment with word info
- Adjust query limits for bookmarked and incorrect words queries
* feat: add default value for ExistingCognitoClientId in template.yaml
- Set default to an empty string to ensure compatibility with templates using this parameter without explicitly specifying a value.
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: SpeakingHandler getStringOrNull 컴파일 에러 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* fix: Bedrock 키워드(meaningKo 포함)를 article에 저장하도록 수정
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* feat: add dashboard stats API and enhance news stats tracking
- Introduce `/stats/dashboard` API for retrieving integrated user stats (today, overall, weekly progress, and level distribution)
- Update `UserStats` model to include additional fields for news stats (newsRead, newsQuizCompleted, newsQuizPerfect, newsWordsCollected, etc.)
- Add atomic updates to track news reading, quiz, and word stats in `UserStatsRepository`
- Modify CloudFormation `template.yaml` to register the new `/stats/dashboard` endpoint
* refactor: format code with consistent indentation and spacing
- Apply consistent formatting to improve code readability across multiple files
- Adjust indentation, spacing, and alignment in model classes, DTOs, and repository methods
* fix: filter by ARTICLE# prefix in findById to avoid returning bookmark records
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feature : Speaking Table & Function template.yaml 파일에 추가 (#513)
* fix: BadgeRepository 클라이언트 초기화 패턴 통일
- 개별 DynamoDbEnhancedClient 생성 대신 AwsClients.dynamoDbEnhanced() 싱글톤 사용
- 다른 Repository들과 동일한 패턴 적용
- 불필요한 import 제거
Closes #396
* feat: EnvConfig 유틸리티 추가 및 환경 변수 검증 적용
환경 변수 미설정 시 명확한 에러 메시지를 제공하는 EnvConfig 유틸리티를 추가하고,
기존 System.getenv 호출을 EnvConfig.getRequired/getOrDefault로 대체함.
- EnvConfig: getRequired, getOrDefault, getIntOrDefault, getLongOrDefault 메서드 제공
- Lambda Cold Start 시점에 환경 변수 누락을 조기 감지
- 기존 Config 클래스(WebSocketConfig, RoomTokenConfig) EnvConfig 사용으로 통일
Closes #403
* refactor: TestService submitTest 메서드 책임 분리
submitTest 메서드를 단일 책임 원칙에 맞게 리팩토링:
- gradeAnswers(): 답안 채점 및 결과 집계
- isAnswerCorrect(): 단일 답안 정답 여부 판단
- buildResultItem(): 결과 항목 생성
- saveTestResult(): 테스트 결과 저장
- GradingResult record: 채점 결과 캡슐화
TestService와 TestCommandService 모두 동일하게 적용
Closes #404
* refactor: 하드코딩된 설정값 환경 변수로 외부화
각 도메인별 Config 클래스를 생성하여 하드코딩된 값들을 환경 변수로 설정 가능하게 변경.
기본값이 있어 환경 변수 미설정 시에도 기존 동작 유지.
## 새로 추가된 Config 클래스
- GrammarConfig: SESSION_TTL_DAYS, MAX_HISTORY_MESSAGES, MAX_TOKENS 등
- GameConfig: TOTAL_ROUNDS, ROUND_TIME_LIMIT, QUICK_GUESS_THRESHOLD_MS
- VocabularyConfig: NEW_WORDS_COUNT, REVIEW_WORDS_COUNT, 상태 전이 임계값 등
## 지원하는 환경 변수
- GRAMMAR_SESSION_TTL_DAYS, GRAMMAR_MAX_HISTORY_MESSAGES, GRAMMAR_MAX_TOKENS
- GAME_TOTAL_ROUNDS, GAME_ROUND_TIME_LIMIT, GAME_QUICK_GUESS_THRESHOLD_MS
- VOCAB_NEW_WORDS_COUNT, VOCAB_REVIEW_WORDS_COUNT
- VOCAB_TRANSITION_TO_REVIEWING, VOCAB_TRANSITION_TO_MASTERED
Closes #406
* test: StudyLevel enum 단위 테스트 추가
* test: Difficulty enum 단위 테스트 추가
* test: StudyConfig 단위 테스트 추가
* test: EnvConfig 단위 테스트 추가
* test: PaginatedResult 단위 테스트 추가
* test: JsonUtil 단위 테스트 추가
* test: CursorUtil 단위 테스트 추가
* test: CommonErrorCode 단위 테스트 추가
* test: CommonException 단위 테스트 추가
* test: BadgeType enum 단위 테스트 추가
* test: BadgeKey 상수 단위 테스트 추가
* test: WordStatus enum 단위 테스트 추가
* test: TestType enum 단위 테스트 추가
* test: VocabularyConfig 단위 테스트 추가
* test: VocabKey 상수 단위 테스트 추가
* test: VocabularyErrorCode 단위 테스트 추가
* test: VocabularyException 단위 테스트 추가
* test: SpacedRepetitionContext 단위 테스트 추가
* test: GrammarLevel enum 단위 테스트 추가
* test: GrammarConfig 단위 테스트 추가
* test: GrammarErrorCode 단위 테스트 추가
* test: GrammarException 단위 테스트 추가
* test: GameStatus enum 단위 테스트 추가
* test: GameConfig 단위 테스트 추가
* test: ChattingErrorCode 단위 테스트 추가
* test: ChattingException 단위 테스트 추가
* fix: OPIc FeedbackResponse.java 문법 오류 수정
* style: AwsClients 코드 포맷팅
* style: EnvConfig 코드 포맷팅
* style: RoomTokenConfig 코드 포맷팅
* style: WebSocketConfig 코드 포맷팅
* style: JsonUtil 코드 포맷팅
* style: GameConfig 코드 포맷팅
* style: GrammarConfig 코드 포맷팅
* style: GrammarKey 코드 포맷팅
* style: GrammarErrorCode 코드 포맷팅
* style: GrammarException 코드 포맷팅
* style: BedrockGrammarCheckFactory 코드 포맷팅
* style: GrammarConversationService 코드 포맷팅
* style: FeedbackResponse 코드 포맷팅
* style: SessionReportResponse 코드 포맷팅
* style: SpeakingError 코드 포맷팅
* style: SpeakingErrorType 코드 포맷팅
* style: OPIcException 코드 포맷팅
* style: OPIcAnswer 코드 포맷팅
* style: OPIcQuestion 코드 포맷팅
* style: OPIcSession 코드 포맷팅
* style: OPIcRepository 코드 포맷팅
* style: FeedbackService 코드 포맷팅
* style: TranscribeProxyService 코드 포맷팅
* style: VocabularyConfig 코드 포맷팅
* style: DailyStudyCommandService 코드 포맷팅
* style: TestCommandService 코드 포맷팅
* style: TestService 코드 포맷팅
* style: CommonErrorCodeSpec 코드 포맷팅
* style: JsonUtilSpec 코드 포맷팅
* style: BadgeTypeSpec 코드 포맷팅
* style: ChattingErrorCodeSpec 코드 포맷팅
* style: GrammarLevelSpec 코드 포맷팅
* style: GrammarErrorCodeSpec 코드 포맷팅
* style: VocabularyErrorCodeSpec 코드 포맷팅
* feature : OPIc 세션관리 + 답변 처리 파이프라인 구현 (#413)
* feat : OPIc 질문 & 세션 관련 dto 생성
* refactor : @DynamoDbBean 주석 추가
* feat : 주제 + 소주제 + 레벨로 오픽 질문 조회 추가
* feat : OPIc 세션, 질문, 답변 종합 handler 구현
* feat : 오픽 주제, 소주제별 seed 데이터 추가
* refactor : Transcribe API KEY 환경변수명 수정
* refactor : Bedrock에 사용하는 클로드 모델 변경
* refactor : S3 Key 대신 Proxy에서 요청하는 Base64 값으로 변환
* feat: GAME_START, ROUND_END 메시지에 serverTime 추가
- broadcastGameStart(): serverTime, roundDuration 필드 추가
- broadcastRoundEnd(): serverTime, roundStartTime, roundDuration 필드 추가
- GameService.endRound(): data에 roundStartTime, roundDuration 포함
- 타이머 동기화 버그 수정을 위한 서버 시간 제공
* feat: WebSocketMessageHelper 유틸리티 클래스 추가
- domain 필드 포함 메시지 생성 헬퍼
- DOMAIN_CHAT, DOMAIN_GAME 상수 정의
- buildChatMessage(), buildGameMessage() 메서드
* feat: 모든 WebSocket 메시지에 domain 필드 추가
- ScoreUpdateMessage에 domain 필드 추가
- broadcastGameStart에 domain:"game" 추가
- broadcastRoundEnd에 domain:"game" 추가
- broadcastCorrectAnswerMessage에 domain:"game" 추가
- handleCommandResult 시스템 메시지에 domain:"game" 추가
- handleRegularMessage 채팅 메시지에 domain:"chat" 추가
Closes #426, #427
* feat: GameSession 모델 클래스 생성
- DynamoDB Enhanced Client 어노테이션 적용
- GSI1: roomId로 활성 게임 세션 조회 가능
- 게임 상태 관리용 헬퍼 메서드 포함
Closes #428
* feat: GameSessionRepository 구현
- 기본 CRUD (save, findById, delete)
- roomId로 활성/전체 게임 세션 조회
- 상태, 라운드, 점수 업데이트 메서드
- 정답자 추가, 힌트 사용, 게임 종료 처리
Closes #429
* refactor: ChatRoom에서 게임 필드 분리
- 게임 관련 필드 제거 (gameStatus, currentRound 등)
- activeGameSessionId 필드 추가
- 게임 상태는 GameSession으로 분리됨
Note: 의존 코드 수정은 #431에서 진행
Closes #430
* refactor: GameSession 기반으로 전체 게임 로직 리팩토링
- GameService: ChatRoom 대신 GameSession 사용
- GameStatsService: GameSession 매개변수로 변경
- CommandService: GameSession 기반 점수 조회
- GameHandler: GameSession 기반 REST API
- WebSocketMessageHandler: GameSession 기반 브로드캐스트
- GameStatusResponse, ScoreboardResponse: GameSession 매개변수
Closes #431
* feat: GameSessionHandler Lambda 및 게임 세션 API 구현
- POST /rooms/{roomId}/games - 게임 세션 생성
- GET /games/{gameSessionId} - 게임 상태 조회 (재접속용)
- POST /games/{gameSessionId}/start - 게임 시작
- POST /games/{gameSessionId}/stop - 게임 종료
모든 응답에 serverTime 포함 (타이머 동기화)
출제자에게만 currentWord 포함
Closes #432, #433
* feat: 게임 시작 7분 후 자동 종료 기능 구현
- GameConfig에 gameTimeLimit() 메서드 추가 (기본값: 420초)
- GameSchedulerClient 유틸리티 클래스 생성 (EventBridge Scheduler 연동)
- GameService에 스케줄 생성/취소 로직 추가
- GameAutoCloseHandler Lambda 함수 생성
- template.yaml에 Lambda, IAM Role, Schedule Group 추가
Closes #417
* fix : 메모리 증가 및 Lambda 응답 제한 시간 Cognito 트리거 제한시간과 동일하게 수정 (#439)
* feat: 캐치마인드 게임 방 분리 기능 구현 (#455)
- Room 타입 분리 (CHAT/GAME)
- RoomType, RoomStatus enum 추가
- ChatRoom 모델에 type, gameType, gameSettings, status, hostId 필드 추가
- GameSettings 모델 추가
- 방 생성/조회 API 수정
- CreateRoomRequest에 type, gameType, gameSettings 필드 추가
- 방 목록 조회 시 type, gameType, status 필터 지원
- 게임 시작 조건 검증
- GAME 타입 방에서만 게임 시작 가능 (GAME_007 에러)
- 게임 재시작 API 구현 (#452)
- POST /rooms/{roomId}/game/restart 엔드포인트 추가
- 방장만 재시작 가능 (GAME_009 에러)
- 게임 진행 중 재시작 불가 (GAME_008 에러)
- 방장 변경 로직 구현 (#453)
- 방장 퇴장 시 다음 멤버에게 자동 이전
- 모든 멤버 퇴장 시 방 자동 삭제
- WebSocket 메시지 타입 추가 (#454)
- ROOM_STATUS_CHANGE, HOST_CHANGE 메시지 타입 추가
- WebSocketMessageHelper에 빌더 메서드 추가
- 테스트 추가
- RoomType, RoomStatus enum 테스트
- GameSettings 모델 테스트
- ChattingErrorCode 테스트 업데이트
Related: #440, #441, #442, #443, #444, #445, #446
Closes: #447, #448, #449, #450, #451, #452, #453, #454
* feat: 참가자 닉네임 및 방장 변경 WebSocket 알림 구현 (#456)
- RoomParticipant DTO 추가 (userId, nickname, isHost)
- ChatRoomQueryService에 닉네임 조회 메서드 추가
- getParticipantsWithNicknames(): 참가자 목록 + 닉네임
- getHostNickname(): 방장 닉네임 조회
- ChatRoomHandler.getRoom() 응답에 participants, hostNickname 추가
- ChatRoomCommandService.leaveRoom()에서 방장 변경 시 WebSocket 브로드캐스트
Related: #440
* fix: ChatRoomFunction에 UserTable DynamoDB 권한 추가
- 참가자/방장 닉네임 조회를 위한 UserTable 읽기 권한 추가
- DynamoDBReadPolicy로 UserTable 접근 허용
Fixes #457
* fix: GameSettings에 @DynamoDbBean 어노테이션 추가
- DynamoDB Enhanced Client가 중첩 객체를 직렬화/역직렬화할 수 있도록 수정
- ChatRoom 저장/조회 시 GameSettings 변환 오류 해결
Fixes #457
* fix: ChatRoomFunction에 WEBSOCKET_ENDPOINT 환경변수 및 권한 추가
- leaveRoom에서 WebSocketBroadcaster 사용을 위한 환경변수 추가
- execute-api:ManageConnections 권한 추가
* fix: WebSocket Lambda 함수들에 WEBSOCKET_ENDPOINT 환경변수 추가
- WebSocketConnectFunction에 WEBSOCKET_ENDPOINT 추가
- WebSocketD…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
OPIc 답변 제출 시 발생하는 API Gateway 타임아웃(504 Error)을 해결하기 위해, 핵심 로직을 비동기 아키텍처로 전환했습니다. 또한, 세션 완료 시 사용자에게 상세 리포트를 이메일로 자동 발송하는 기능을 추가했습니다.
작업 내용
기존 로직: 제출 -> STT -> AI 피드백 -> 응답 (평균 20초 이상 소요로 인한 504 에러 발생)
변경 로직: