-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenapi.json.bak
More file actions
1 lines (1 loc) · 30.9 KB
/
openapi.json.bak
File metadata and controls
1 lines (1 loc) · 30.9 KB
1
{"openapi":"3.0.0","paths":{"/auth/login":{"post":{"description":"선생님 계정으로 로그인합니다. 회원가입 없이 관리자가 지정한 패스워드 + 본인 이름으로 로그인합니다.","operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":"로그인에 성공했습니다.","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"로그인에 성공했습니다."},"data":{"$ref":"#/components/schemas/LoginResponseDto"}}}]}}}},"400":{"description":"존재하지 않는 선생님 또는 잘못된 비밀번호"},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"선생님 로그인","tags":["Auth - 인증"]}},"/api/channels":{"get":{"description":"선생님이 소유한 채널 목록을 조회합니다.","operationId":"ChannelsController_getChannels","parameters":[],"responses":{"200":{"description":"채널 목록 조회 성공","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"채널 목록 조회 성공"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ChannelListResponseDto"}}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"채널 목록 조회","tags":["Channels - 채널"]}},"/api/channels/set":{"post":{"description":"채널의 수업 설정(시간, 대진표 등)을 저장합니다. 채널 활성화 직후 이 API를 호출합니다.","operationId":"ChannelsController_setChannel","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetChannelDto"}}}},"responses":{"200":{"description":"수업 설정이 저장되었습니다.","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"수업 설정이 저장되었습니다."},"data":{"$ref":"#/components/schemas/SetChannelResponseDto"}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"수업 설정","tags":["Channels - 채널"]}},"/api/channels/{channelId}/activate":{"post":{"description":"비활성화된 채널을 활성화합니다. 활성화 후 수업 설정 화면으로 이동합니다.","operationId":"ChannelsController_activateChannel","parameters":[{"name":"channelId","required":true,"in":"path","description":"채널 ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"채널이 활성화되었습니다.","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"채널이 활성화되었습니다."},"data":{"$ref":"#/components/schemas/ActivateChannelResponseDto"}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"채널 활성화","tags":["Channels - 채널"]}},"/api/channels/{channelId}/finish":{"post":{"description":"수업을 종료하고 채널을 비활성화합니다.","operationId":"ChannelsController_finishChannel","parameters":[{"name":"channelId","required":true,"in":"path","description":"채널 ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"수업이 종료되었습니다. 채널이 비활성화됩니다.","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"수업이 종료되었습니다. 채널이 비활성화됩니다."},"data":{"type":"null","example":null}}}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"수업 종료","tags":["Channels - 채널"]}},"/api/channels/{channelId}":{"get":{"description":"QR 코드 스캔으로 채널에 입장하고 방 목록을 조회합니다. 인증이 필요하지 않습니다.","operationId":"ChannelsController_getRooms","parameters":[{"name":"channelId","required":true,"in":"path","description":"채널 ID (QR코드에 포함)","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"방 목록 조회 성공","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"방 목록 조회 성공"},"data":{"type":"array","items":{"$ref":"#/components/schemas/RoomListResponseDto"}}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"방 목록 조회 (학생용)","tags":["Channels - 채널"]}},"/api/channels/{channelId}/rooms/{roomId}/join":{"post":{"description":"학생이 특정 방에 입장합니다. 인증이 필요하지 않습니다.","operationId":"RoomsController_joinRoom","parameters":[{"name":"channelId","required":true,"in":"path","description":"채널 ID","schema":{"example":1,"type":"number"}},{"name":"roomId","required":true,"in":"path","description":"방 ID","schema":{"example":101,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomDto"}}}},"responses":{"200":{"description":"방 입장에 성공했습니다.","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"방 입장에 성공했습니다."},"data":{"$ref":"#/components/schemas/JoinRoomResponseDto"}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"summary":"방 입장","tags":["Rooms - 방"]}},"/api/students":{"get":{"description":"선생님에게 등록된 학생 목록을 조회합니다. 토큰을 통해 선생님을 구분하고, 해당 선생님에게 등록된 학생만 반환합니다.","operationId":"StudentsController_getStudents","parameters":[{"name":"name","required":false,"in":"query","description":"이름 검색 필터","schema":{"example":"김철수","type":"string"}}],"responses":{"200":{"description":"학생 목록 조회 성공","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"학생 목록 조회 성공"},"data":{"type":"array","items":{"$ref":"#/components/schemas/StudentResponseDto"}}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"학생 목록 조회","tags":["Students - 학생"]},"post":{"description":"새 학생을 등록합니다.","operationId":"StudentsController_createStudent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStudentDto"}}}},"responses":{"200":{"description":"학생이 등록되었습니다.","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"학생이 등록되었습니다."},"data":{"$ref":"#/components/schemas/StudentResponseDto"}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"학생 추가","tags":["Students - 학생"]}},"/api/students/{studentId}":{"delete":{"description":"등록된 학생을 삭제합니다. 진행 중인 대국이 있으면 삭제할 수 없습니다.","operationId":"StudentsController_deleteStudent","parameters":[{"name":"studentId","required":true,"in":"path","description":"학생 ID","schema":{"example":1,"type":"number"}}],"responses":{"200":{"description":"학생이 삭제되었습니다.","content":{"application/json":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"학생이 삭제되었습니다."},"data":{"type":"null","example":null}}}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"학생 삭제","tags":["Students - 학생"]}},"/api/matches/history/download":{"get":{"description":"경기 기록을 엑셀 파일로 다운로드합니다.","operationId":"MatchesController_downloadHistory","parameters":[{"name":"channelId","required":true,"in":"query","description":"채널 ID","schema":{"example":1,"type":"number"}},{"name":"startDate","required":true,"in":"query","description":"조회 시작일 (yyyy-mm-dd)","schema":{"example":"2026-01-01","type":"string"}},{"name":"endDate","required":true,"in":"query","description":"조회 종료일 (yyyy-mm-dd)","schema":{"example":"2026-01-31","type":"string"}}],"responses":{"200":{"description":"다운로드가 시작되었습니다.","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"다운로드가 시작되었습니다."},"data":{"type":"null","example":null}}}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"엑셀 다운로드","tags":["Matches - 경기 기록"]}},"/api/matches/history":{"get":{"description":"특정 기간의 경기 기록을 조회합니다. 페이지네이션 및 필터링을 지원합니다.","operationId":"MatchesController_getHistory","parameters":[{"name":"start_date","required":true,"in":"query","description":"조회 시작일 (yyyy-mm-dd)","schema":{"example":"2026-01-01","type":"string"}},{"name":"end_date","required":true,"in":"query","description":"조회 종료일 (yyyy-mm-dd)","schema":{"example":"2026-01-31","type":"string"}},{"name":"student_id","required":false,"in":"query","description":"학생 ID 필터","schema":{"example":101,"type":"number"}},{"name":"channel_id","required":false,"in":"query","description":"채널 ID 필터","schema":{"example":1,"type":"number"}},{"name":"page","required":false,"in":"query","description":"페이지 번호","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"페이지당 항목 수 (최대 100)","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"정렬 순서","schema":{"default":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"경기 기록 조회 성공","content":{"application/json":{"schema":{"allOf":[{"properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"경기 기록 조회 성공"},"data":{"$ref":"#/components/schemas/HistoryResponseDto"}}}]}}}},"400":{"description":"Bad Request - 잘못된 요청","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"401":{"description":"Unauthorized - 인증 실패","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"403":{"description":"Forbidden - 권한 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"404":{"description":"Not Found - 리소스 없음","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"409":{"description":"Conflict - 충돌","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}},"500":{"description":"Internal Server Error - 서버 에러","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponseDto"}}}}},"security":[{"access-token":[]}],"summary":"경기 기록 조회","tags":["Matches - 경기 기록"]}}},"info":{"title":"Go/Chess Timer API","description":"바둑/체스 타이머 애플리케이션을 위한 REST API","version":"1.0.0","contact":{"name":"전호영","url":"","email":""}},"tags":[],"servers":[{"url":"http://localhost:3000","description":"Development"}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"Authorization","description":"JWT 토큰을 입력하세요","in":"header"}},"schemas":{"BaseResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"성공 여부","example":true},"message":{"type":"string","description":"응답 메시지","example":"처리에 성공했습니다."}},"required":["success","message"]},"LoginResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"API 호출 및 소켓 연결용 JWT 토큰","example":"eyJhbGciOiJIUzI1NiIsIn..."}},"required":["accessToken"]},"LoginDto":{"type":"object","properties":{"id":{"type":"string","description":"선생님 이름 (로그인 ID)","example":"김철수"},"password":{"type":"string","description":"관리자 지정 패스워드","example":"eXampLeP@ss"}},"required":["id","password"]},"ErrorResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"성공 여부","example":false},"statusCode":{"type":"number","description":"HTTP 상태 코드","example":400},"message":{"type":"string","description":"에러 메시지","example":"에러 메시지"}},"required":["success","statusCode","message"]},"ChannelListResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"채널 ID","example":1},"status":{"type":"string","description":"채널 상태","enum":["ACTIVATE","DEACTIVATE"],"example":"ACTIVATE"},"roomCounts":{"type":"number","description":"방 개수","example":6},"createdAt":{"format":"date-time","type":"string","description":"생성 시간 (ISO 8601)","example":"2025-12-31T04:09:42.059Z"}},"required":["id","status","roomCounts","createdAt"]},"SetChannelConfigResponseDto":{"type":"object","properties":{"time":{"type":"number","description":"대국 시간 (분)","example":20},"autoStart":{"type":"boolean","description":"자동 시작 여부","example":true}},"required":["time","autoStart"]},"SetChannelResponseDto":{"type":"object","properties":{"channelId":{"type":"number","description":"채널 ID","example":1},"config":{"$ref":"#/components/schemas/SetChannelConfigResponseDto"}},"required":["channelId","config"]},"MatchDto":{"type":"object","properties":{"black":{"type":"string","description":"흑 플레이어 이름","example":"유재석"},"white":{"type":"string","description":"백 플레이어 이름","example":"하하"}},"required":["black","white"]},"SetConfigDto":{"type":"object","properties":{"time":{"type":"number","description":"대국 시간 (분)","example":20,"minimum":1},"autoStart":{"type":"boolean","description":"자동 시작 여부 (true: AUTO, false: MANUAL)","example":true},"matches":{"description":"대진표 배열","example":[{"black":"유재석","white":"하하"},{"black":"주우재","white":"허경환"}],"type":"array","items":{"$ref":"#/components/schemas/MatchDto"}}},"required":["time","autoStart","matches"]},"SetChannelDto":{"type":"object","properties":{"channelId":{"type":"number","description":"채널 ID","example":1},"set":{"description":"수업 설정","allOf":[{"$ref":"#/components/schemas/SetConfigDto"}]}},"required":["channelId","set"]},"ActivateChannelResponseDto":{"type":"object","properties":{"channelId":{"type":"number","description":"채널 ID","example":1},"status":{"type":"string","description":"채널 상태","enum":["ACTIVATE","DEACTIVATE"],"example":"ACTIVATE"}},"required":["channelId","status"]},"RoomListResponseDto":{"type":"object","properties":{"roomId":{"type":"number","description":"방 ID","example":101},"status":{"type":"string","description":"방 상태","enum":["WAITING","PLAYING"],"example":"WAITING"},"blackPlayerName":{"type":"object","description":"흑 플레이어 이름","example":"김철수"},"whitePlayerName":{"type":"object","description":"백 플레이어 이름","example":"이영희"}},"required":["roomId","status"]},"PlayerResponseDto":{"type":"object","properties":{"name":{"type":"string","description":"플레이어 이름","example":"김철수"},"isConnected":{"type":"boolean","description":"접속 여부","example":true},"status":{"type":"string","description":"준비 상태","example":"WAITING"},"remainingTimeSeconds":{"type":"number","description":"잔여 시간 (초)","example":180}},"required":["name","isConnected","status","remainingTimeSeconds"]},"PlayersResponseDto":{"type":"object","properties":{"black":{"description":"흑 플레이어","allOf":[{"$ref":"#/components/schemas/PlayerResponseDto"}]},"white":{"description":"백 플레이어","allOf":[{"$ref":"#/components/schemas/PlayerResponseDto"}]}},"required":["black","white"]},"RoomResponseDto":{"type":"object","properties":{"roomId":{"type":"number","description":"방 ID","example":101},"status":{"type":"string","description":"방 상태","enum":["WAITING","READY","PLAYING","JUDGING","TIMEOUT","FINISHED"],"example":"WAITING"},"startMode":{"type":"string","description":"시작 모드","enum":["AUTO","MANUAL"],"example":"MANUAL"},"currentTurn":{"type":"string","description":"현재 턴","enum":["BLACK","WHITE"],"example":"BLACK"},"lastMoveTime":{"type":"string","description":"마지막 착수 시간 (ISO 8601)","example":"2026-01-05T14:30:05.123Z"},"players":{"description":"플레이어 정보","allOf":[{"$ref":"#/components/schemas/PlayersResponseDto"}]}},"required":["roomId","status","startMode","currentTurn","lastMoveTime","players"]},"JoinRoomResponseDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"API 호출 및 소켓 연결용 JWT 토큰","example":"eyJh..."},"room":{"description":"방 정보","allOf":[{"$ref":"#/components/schemas/RoomResponseDto"}]}},"required":["accessToken","room"]},"JoinRoomDto":{"type":"object","properties":{"side":{"type":"string","description":"진영","enum":["BLACK","WHITE"],"example":"BLACK"},"name":{"type":"string","description":"학생 이름","example":"김철수"},"password":{"type":"string","description":"학생 전화번호 뒷 4자리","example":"1234"}},"required":["side","name","password"]},"StudentResponseDto":{"type":"object","properties":{"id":{"type":"number","description":"학생 ID","example":1},"name":{"type":"string","description":"학생 이름","example":"김철수"},"phoneNumber":{"type":"string","description":"학생 전화번호","example":"010-1234-1234"}},"required":["id","name","phoneNumber"]},"CreateStudentDto":{"type":"object","properties":{"name":{"type":"string","description":"학생 이름","example":"박전학"},"phoneNumber":{"type":"string","description":"학생 전화번호","example":"010-9999-8888","pattern":"^01[0-9]-[0-9]{3,4}-[0-9]{4}$"}},"required":["name","phoneNumber"]},"AppliedFiltersDto":{"type":"object","properties":{"startDate":{"type":"string","example":"2026-01-01"},"endDate":{"type":"string","example":"2026-01-31"},"teacherId":{"type":"number","example":5},"studentId":{"type":"number","example":101},"channelId":{"type":"number","example":1}}},"HistoryMetaDto":{"type":"object","properties":{"page":{"type":"number","description":"현재 페이지 번호","example":1},"limit":{"type":"number","description":"페이지당 항목 수","example":20},"totalCount":{"type":"number","description":"전체 경기 수","example":156},"totalPages":{"type":"number","description":"전체 페이지 수","example":8},"appliedFilters":{"description":"적용된 필터 정보","allOf":[{"$ref":"#/components/schemas/AppliedFiltersDto"}]}},"required":["page","limit","totalCount","totalPages","appliedFilters"]},"DailySummaryDto":{"type":"object","properties":{"gamesCount":{"type":"number","description":"해당 날짜 경기 수","example":12},"totalPlayTimeSeconds":{"type":"number","description":"해당 날짜 총 경기 시간 (초)","example":21600}},"required":["gamesCount","totalPlayTimeSeconds"]},"TeacherInfoDto":{"type":"object","properties":{"id":{"type":"number","description":"선생님 ID","example":5},"name":{"type":"string","description":"선생님 이름","example":"김철수"}},"required":["id","name"]},"PlayerInfoDto":{"type":"object","properties":{"id":{"type":"number","description":"학생 ID","example":101},"name":{"type":"string","description":"학생 이름","example":"박지훈"},"isWinner":{"type":"boolean","description":"승자 여부","example":true}},"required":["id","name","isWinner"]},"PlayersDto":{"type":"object","properties":{"black":{"description":"흑 플레이어","allOf":[{"$ref":"#/components/schemas/PlayerInfoDto"}]},"white":{"description":"백 플레이어","allOf":[{"$ref":"#/components/schemas/PlayerInfoDto"}]}},"required":["black","white"]},"GameResultDto":{"type":"object","properties":{"winner":{"type":"string","description":"승자","enum":["BLACK","WHITE"],"example":"BLACK"},"reason":{"type":"string","description":"승리 사유","enum":["TIMEOUT","RESIGN","JUDGE","FOUL"],"example":"TIMEOUT"}},"required":["winner","reason"]},"DurationDto":{"type":"object","properties":{"playTimeSeconds":{"type":"number","description":"경기 시간 (초)","example":1820},"startedAt":{"type":"string","description":"시작 시간","example":"2026-01-05T10:00:00Z"},"endedAt":{"type":"string","description":"종료 시간","example":"2026-01-05T10:30:20Z"}},"required":["playTimeSeconds","startedAt","endedAt"]},"GameDto":{"type":"object","properties":{"matchId":{"type":"string","description":"경기 고유 ID","example":"M003"},"channelId":{"type":"number","description":"채널 ID","example":1},"teacher":{"description":"선생님 정보","allOf":[{"$ref":"#/components/schemas/TeacherInfoDto"}]},"players":{"description":"플레이어 정보","allOf":[{"$ref":"#/components/schemas/PlayersDto"}]},"result":{"description":"경기 결과","allOf":[{"$ref":"#/components/schemas/GameResultDto"}]},"duration":{"description":"경기 시간 정보","allOf":[{"$ref":"#/components/schemas/DurationDto"}]}},"required":["matchId","channelId","teacher","players","result","duration"]},"DailyMatchesDto":{"type":"object","properties":{"date":{"type":"string","description":"날짜 (yyyy-mm-dd)","example":"2026-01-05"},"dailySummary":{"description":"일별 요약","allOf":[{"$ref":"#/components/schemas/DailySummaryDto"}]},"games":{"description":"경기 목록","type":"array","items":{"$ref":"#/components/schemas/GameDto"}}},"required":["date","dailySummary","games"]},"HistoryResponseDto":{"type":"object","properties":{"meta":{"description":"메타 정보","allOf":[{"$ref":"#/components/schemas/HistoryMetaDto"}]},"matches":{"description":"날짜별 경기 목록","type":"array","items":{"$ref":"#/components/schemas/DailyMatchesDto"}}},"required":["meta","matches"]}}}}