- 기능 구현을 완료한 후 아래 가이드에 따라 모든 테스트가 성공적으로 실행되는지 확인한다.
- 테스트가 실패하면 점수가 0점이 되므로 제출하기 전에 반드시 확인한다.
- 터미널에서
java -version을 실행하여 Java 버전이 21인지 확인한다. - 터미널에서 Mac 또는 Linux 사용자는
./gradlew clean test를 실행하고, Windows 사용자는gradlew.bat clean test또는./gradlew.bat clean test를 실행한다.
- 기능을 구현하기 전
README.md에 구현할 기능 목록을 정리해 추가한다. - Git 커밋 단위는 기능 목록 단위로 한다.
- 프로그램은 사용자가 종료할 때까지 종료되지 않으며, 기능을 수행한 후 초기 화면으로 돌아간다.
- 사용자가 잘못된 값을 입력한 경우
[ERROR]로 시작하는 메시지와 함께IllegalArgumentException을 발생시킨 후 애플리케이션을 종료한다.
크루들이 스터디룸을 예약하는데, 겹치는 예약/노쇼가 반복되며 운영 부담이 커졌다. 스터디룸 예약과 체크인을 관리하는 간단한 콘솔 프로그램을 만든다.
- 시스템이 관리하는 기간은 2026년 1월 1일 ~ 2026년 1월 31일이다.
- 스터디룸은
A,B,C세 개가 있다. - 한 방에는 동시에 하나의 예약만 존재할 수 있다(시간 겹침 금지).
- 주말(토/일) 및 휴일에는 예약/체크인/조회가 불가능하다.
- 휴일 정보는
src/main/resources/holidays.csv로 제공한다(수정 금지).
- 운영 시간: 09:00 ~ 22:00
- 예약 시작/종료는 30분 단위여야 한다.
- 예:
09:00,09:30,10:00
- 예:
- 예약은 최소 30분, 최대 2시간까지 가능하다.
- 예약 종료 시각은 시작 시각보다 늦어야 한다.
- 운영 시간을 벗어나는 예약은 불가능하다.
- 예:
21:30~22:30불가
- 예:
체크인은 예약 시작 시각 기준으로 상태가 결정된다.
- 정상 체크인(ON_TIME): 시작 시각
-10분~+10분사이 체크인 - 지각 체크인(LATE): 시작 시각
+10분 초과~ 예약 종료 이전 체크인 - 노쇼(NO_SHOW): 예약 종료 시각이 지났는데 체크인이 없는 경우
“현재 시각”은
mission-utils의DateTimes.now()를 사용해 계산한다.
- 지각 1회 = 패널티 1점
- 노쇼 1회 = 패널티 2점
- 패널티 점수는 **최근 14일(오늘 제외, 전날까지)**의 기록만 합산한다.
- 패널티가 5점 이상이면 예약 불가 상태(BLOCK) 로 간주한다.
- BLOCK 상태인 크루는 “예약 등록”을 할 수 없다.
- 등록된 크루 목록:
src/main/resources/members.csv(수정 금지) - 기존 예약/체크인 기록:
src/main/resources/reservations.csv(수정 금지)- 예시 데이터에는 1월 초 일부 예약 기록이 포함되어 있으며, 패널티 계산/NO_SHOW 판정 예시에 사용된다.
reservations.csv 형식:
nickname,room,start,end,checkin
빙티,A,2026-01-06 19:00,2026-01-06 20:00,
이든,B,2026-01-06 20:30,2026-01-06 21:30,2026-01-06 20:33
- 입력: 닉네임, 룸(A/B/C), 예약 시작(HH:mm), 예약 종료(HH:mm)
- 규칙:
- 등록되지 않은 닉네임이면 에러
- 주말/휴일이면 에러
- 운영 시간/30분 단위/최대 2시간 등 정책 위반이면 에러
- 기존 예약과 시간이 겹치면 에러(같은 룸 기준)
- BLOCK 상태(최근 14일 패널티 >= 5)인 크루는 예약 불가(에러)
- 동일 크루는 “미래 예약”을 최대 3개까지만 보유 가능(초과 시 에러)
- 출력: 예약 정보와 “예약 완료!” 문구
- 입력: 닉네임, 룸(A/B/C)
- 규칙:
-
체크인은 오늘 날짜의 예약 중,
닉네임과룸이 일치하는 예약에 대해서만 가능하다. -
체크인 가능한 시간 범위는
예약 시작 10분 전부터예약 종료 직전까지다.- 범위를 벗어나면 에러 처리한다.
-
오늘 날짜의 해당 룸 예약이 존재해야 한다(없으면 에러)
-
이미 체크인한 예약이면 에러
-
체크인은 운영일에만 가능(주말/휴일이면 에러)
-
체크인 시각은
DateTimes.now()기준이며, 체크인 후 상태(ON_TIME/LATE)를 출력한다.
-
- 입력: 룸(A/B/C), 조회할 날짜(일)
- 출력:
- 해당 날짜의 예약을 시작 시각 오름차순으로 출력한다.
- 각 예약은 아래 형태로 출력한다.
19:00~20:00 빙티 (PENDING)
- 상태 판정:
- 체크인 시각이 있으면 ON_TIME/LATE로 판정
- 체크인 시각이 없고, “현재 시각”이 예약 종료 이후면 NO_SHOW
- 체크인 시각이 없고, 아직 예약 종료 전이면 PENDING
- 예약이 없으면 “예약이 없습니다.”를 출력한다.
- 전날까지의 기록을 바탕으로(오늘 예약은 제외) 크루들의 최근 14일 패널티를 계산해 출력한다.
- 출력은 패널티 점수 내림차순으로 정렬한다.
- 동점일 때 정렬 기준:
- 패널티 점수 내림차순
- 노쇼 횟수 내림차순
- 지각 횟수 내림차순
- 닉네임 오름차순
- 패널티가 5점 이상인 크루는 이름 옆에
(BLOCK)을 표시한다.
- 모든 입력은
camp.nextstep.edu.missionutils.Console을 사용해 한 줄 단위로 받는다. - 사용자가 잘못된 값을 입력한 경우:
[ERROR]로 시작하는 메시지와 함께IllegalArgumentException을 발생시키고 애플리케이션을 종료한다.
- 아래 예시는 줄바꿈/공백까지 최대한 유사하게 맞춘 예시이며, 실제 구현에서도 입력 안내 문구와 출력 형식을 일관되게 유지한다.
- 프로그램 시작 시
DateTimes.now()를 이용해 오늘 날짜를 출력한다. - 메뉴 출력은 기능 수행 후에도 반복된다.
출력 형식:
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
입력:
- 사용자는
1,2,3,4,Q중 하나를 입력한다. - 소문자
q입력은 허용하지 않는다(형식 오류 처리).
예약할 크루의 닉네임을 입력해 주세요.
룸을 입력해 주세요. (A/B/C)
예약 시작 시각을 입력해 주세요. (HH:mm)
예약 종료 시각을 입력해 주세요. (HH:mm)
- 성공 시 아래 형식으로 출력한다.
예약 완료!
- 룸: A
- 크루: 빙티
- 시간: 19:00~20:00
[ERROR] 해당 시간에는 이미 예약이 존재합니다.
- 닉네임:
members.csv에 없는 닉네임이면 에러
- 룸:
A/B/C만 허용(그 외는 형식 오류)
- 시간(HH:mm):
00:00~23:59의 유효한 시각이어야 한다.09:00~22:00범위를 벗어나는 예약은 불가- 시작/종료가 30분 단위가 아니면 불가
- 종료 <= 시작이면 불가
- 예약 길이가 30분 미만 또는 2시간 초과면 불가
- 같은 룸 기준 시간 겹침:
기존 시작 < 새 종료AND새 시작 < 기존 종료이면 겹침으로 판단한다.
- 미래 예약 개수:
- 동일 크루는 “현재 시각 이후 시작하는 예약”을 최대 3개까지만 가질 수 있다.
체크인할 크루의 닉네임을 입력해 주세요.
체크인할 룸을 입력해 주세요. (A/B/C)
- 체크인 시각은
DateTimes.now()기준으로 출력한다.
ON_TIME 예시:
체크인 완료! (ON_TIME)
- 룸: B
- 크루: 이든
- 체크인 시각: 20:33
LATE 예시:
체크인 완료! (LATE)
- 룸: B
- 크루: 짱수
- 체크인 시각: 18:20
- 오늘 해당 룸에 예약이 없을 때:
[ERROR] 오늘 해당 룸에 예약이 없습니다.
- 이미 체크인한 예약일 때:
[ERROR] 이미 체크인했습니다.
조회할 룸을 입력해 주세요. (A/B/C)
조회할 날짜(일)를 입력해 주세요. (1~31)
- 출력 시작 문구는 아래 형식을 따른다.
룸 A의 1월 7일 스케줄입니다.
- 예약이 있는 경우(시작 시각 오름차순):
19:00~20:00 빙티 (PENDING)
20:30~21:30 이든 (ON_TIME)
- 예약이 없는 경우:
예약이 없습니다.
(ON_TIME): 체크인 시각이 있고, 시작 -10분 ~ +10분(LATE): 체크인 시각이 있고, 시작 +10분 초과 ~ 종료 이전(NO_SHOW): 체크인 시각이 없고, “현재 시각”이 종료 이후(PENDING): 체크인 시각이 없고, “현재 시각”이 종료 이전
- 출력 시작 문구:
패널티 조회 결과 (최근 14일, 오늘 제외/전날까지)
- 각 줄 형식:
- BLOCK 대상이면
(BLOCK)을 크루명 바로 뒤에 붙인다.
- BLOCK 대상이면
- 짱수 (BLOCK): 패널티 6점 (NO_SHOW 3회, LATE 0회)
- 빙티: 패널티 3점 (NO_SHOW 1회, LATE 1회)
- 패널티 점수 내림차순
- 동점이면 노쇼 횟수 내림차순
- 동점이면 지각 횟수 내림차순
- 동점이면 닉네임 오름차순
- 메뉴에서
Q입력 시 아래 문구를 출력하고 종료한다.
프로그램을 종료합니다.
아래 예시는 이해를 돕기 위한 “실행 로그”다.
실제 실행 시DateTimes.now()값(오늘 날짜/시각)에 따라 체크인 시각, PENDING/NO_SHOW 판정 등이 달라질 수 있다.
중요한 것은 입력 프롬프트, 출력 형식, 에러 처리 흐름(에러 발생 시 즉시 종료) 이다.
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
1
예약할 크루의 닉네임을 입력해 주세요.
짱수
룸을 입력해 주세요. (A/B/C)
A
예약 시작 시각을 입력해 주세요. (HH:mm)
18:00
예약 종료 시각을 입력해 주세요. (HH:mm)
19:00
예약 완료!
- 룸: A
- 크루: 짱수
- 시간: 18:00~19:00
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
2
체크인할 크루의 닉네임을 입력해 주세요.
빙티
체크인할 룸을 입력해 주세요. (A/B/C)
A
체크인 완료! (ON_TIME)
- 룸: A
- 크루: 빙티
- 체크인 시각: 18:55
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
3
조회할 룸을 입력해 주세요. (A/B/C)
A
조회할 날짜(일)를 입력해 주세요. (1~31)
6
룸 A의 1월 6일 스케줄입니다.
18:00~19:00 짱수 (PENDING)
19:00~20:00 빙티 (ON_TIME)
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
4
패널티 조회 결과 (최근 14일, 오늘 제외/전날까지)
- 빙티: 패널티 2점 (NO_SHOW 1회, LATE 0회)
- 쿠키: 패널티 1점 (NO_SHOW 0회, LATE 1회)
- 짱수: 패널티 1점 (NO_SHOW 0회, LATE 1회)
- 빙봉: 패널티 0점 (NO_SHOW 0회, LATE 0회)
- 이든: 패널티 0점 (NO_SHOW 0회, LATE 0회)
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
Q
프로그램을 종료합니다.
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
1
예약할 크루의 닉네임을 입력해 주세요.
빙티
룸을 입력해 주세요. (A/B/C)
A
예약 시작 시각을 입력해 주세요. (HH:mm)
19:30
예약 종료 시각을 입력해 주세요. (HH:mm)
20:30
[ERROR] 해당 시간에는 이미 예약이 존재합니다.
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
2
체크인할 크루의 닉네임을 입력해 주세요.
쿠키
체크인할 룸을 입력해 주세요. (A/B/C)
A
[ERROR] 오늘 해당 룸에 예약이 없습니다.
오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
1
예약할 크루의 닉네임을 입력해 주세요.
이든
룸을 입력해 주세요. (A/B/C)
B
예약 시작 시각을 입력해 주세요. (HH:mm)
18:7a
[ERROR] 잘못된 형식을 입력하였습니다.