Skip to content

우테코 7기 최종코테 문제인 "출석"에 기반한 자체 제작 문제입니다.

Notifications You must be signed in to change notification settings

khcho96/java-rooom-reservation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

우아한테크코스 스터디룸 예약 관리

🧪 테스트 실행 가이드

  • 기능 구현을 완료한 후 아래 가이드에 따라 모든 테스트가 성공적으로 실행되는지 확인한다.
  • 테스트가 실패하면 점수가 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-utilsDateTimes.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

🧩 구현해야 할 기능

1) 예약 등록

  • 입력: 닉네임, 룸(A/B/C), 예약 시작(HH:mm), 예약 종료(HH:mm)
  • 규칙:
    • 등록되지 않은 닉네임이면 에러
    • 주말/휴일이면 에러
    • 운영 시간/30분 단위/최대 2시간 등 정책 위반이면 에러
    • 기존 예약과 시간이 겹치면 에러(같은 룸 기준)
    • BLOCK 상태(최근 14일 패널티 >= 5)인 크루는 예약 불가(에러)
    • 동일 크루는 “미래 예약”을 최대 3개까지만 보유 가능(초과 시 에러)
  • 출력: 예약 정보와 “예약 완료!” 문구

2) 체크인

  • 입력: 닉네임, 룸(A/B/C)
  • 규칙:
    • 체크인은 오늘 날짜의 예약 중, 닉네임이 일치하는 예약에 대해서만 가능하다.

    • 체크인 가능한 시간 범위는 예약 시작 10분 전부터 예약 종료 직전까지다.

      • 범위를 벗어나면 에러 처리한다.
    • 오늘 날짜의 해당 룸 예약이 존재해야 한다(없으면 에러)

    • 이미 체크인한 예약이면 에러

    • 체크인은 운영일에만 가능(주말/휴일이면 에러)

    • 체크인 시각은 DateTimes.now() 기준이며, 체크인 후 상태(ON_TIME/LATE)를 출력한다.

3) 룸 스케줄 조회

  • 입력: 룸(A/B/C), 조회할 날짜(일)
  • 출력:
    • 해당 날짜의 예약을 시작 시각 오름차순으로 출력한다.
    • 각 예약은 아래 형태로 출력한다.
      • 19:00~20:00 빙티 (PENDING)
    • 상태 판정:
      • 체크인 시각이 있으면 ON_TIME/LATE로 판정
      • 체크인 시각이 없고, “현재 시각”이 예약 종료 이후면 NO_SHOW
      • 체크인 시각이 없고, 아직 예약 종료 전이면 PENDING
    • 예약이 없으면 “예약이 없습니다.”를 출력한다.

4) 패널티/예약불가 크루 조회

  • 전날까지의 기록을 바탕으로(오늘 예약은 제외) 크루들의 최근 14일 패널티를 계산해 출력한다.
  • 출력은 패널티 점수 내림차순으로 정렬한다.
  • 동점일 때 정렬 기준:
    1. 패널티 점수 내림차순
    2. 노쇼 횟수 내림차순
    3. 지각 횟수 내림차순
    4. 닉네임 오름차순
  • 패널티가 5점 이상인 크루는 이름 옆에 (BLOCK) 을 표시한다.

⌨️ 입출력 요구 사항(상세)

공통 규칙

  • 모든 입력은 camp.nextstep.edu.missionutils.Console 을 사용해 한 줄 단위로 받는다.
  • 사용자가 잘못된 값을 입력한 경우:
    • [ERROR] 로 시작하는 메시지와 함께 IllegalArgumentException 을 발생시키고 애플리케이션을 종료한다.
  • 아래 예시는 줄바꿈/공백까지 최대한 유사하게 맞춘 예시이며, 실제 구현에서도 입력 안내 문구와 출력 형식을 일관되게 유지한다.

0) 초기 화면(메뉴)

  • 프로그램 시작 시 DateTimes.now() 를 이용해 오늘 날짜를 출력한다.
  • 메뉴 출력은 기능 수행 후에도 반복된다.

출력 형식:

오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료

입력:

  • 사용자는 1, 2, 3, 4, Q 중 하나를 입력한다.
  • 소문자 q 입력은 허용하지 않는다(형식 오류 처리).

1) 예약 등록 입출력

입력 흐름

예약할 크루의 닉네임을 입력해 주세요.
룸을 입력해 주세요. (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개까지만 가질 수 있다.

2) 체크인 입출력

입력 흐름

체크인할 크루의 닉네임을 입력해 주세요.
체크인할 룸을 입력해 주세요. (A/B/C)

출력(성공)

  • 체크인 시각은 DateTimes.now() 기준으로 출력한다.

ON_TIME 예시:

체크인 완료! (ON_TIME)
- 룸: B
- 크루: 이든
- 체크인 시각: 20:33

LATE 예시:

체크인 완료! (LATE)
- 룸: B
- 크루: 짱수
- 체크인 시각: 18:20

체크인 관련 에러 예시

  • 오늘 해당 룸에 예약이 없을 때:
[ERROR] 오늘 해당 룸에 예약이 없습니다.
  • 이미 체크인한 예약일 때:
[ERROR] 이미 체크인했습니다.

3) 룸 스케줄 조회 입출력

입력 흐름

조회할 룸을 입력해 주세요. (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) : 체크인 시각이 없고, “현재 시각”이 종료 이전

4) 패널티/예약불가 크루 조회 입출력

출력

  • 출력 시작 문구:
패널티 조회 결과 (최근 14일, 오늘 제외/전날까지)
  • 각 줄 형식:
    • BLOCK 대상이면 (BLOCK) 을 크루명 바로 뒤에 붙인다.
- 짱수 (BLOCK): 패널티 6점 (NO_SHOW 3회, LATE 0회)
- 빙티: 패널티 3점 (NO_SHOW 1회, LATE 1회)

정렬(출력 순서)

  • 패널티 점수 내림차순
  • 동점이면 노쇼 횟수 내림차순
  • 동점이면 지각 횟수 내림차순
  • 동점이면 닉네임 오름차순

5) 종료

  • 메뉴에서 Q 입력 시 아래 문구를 출력하고 종료한다.
프로그램을 종료합니다.

🖥️ 실행 결과 예시

아래 예시는 이해를 돕기 위한 “실행 로그”다.
실제 실행 시 DateTimes.now() 값(오늘 날짜/시각)에 따라 체크인 시각, PENDING/NO_SHOW 판정 등이 달라질 수 있다.
중요한 것은 입력 프롬프트, 출력 형식, 에러 처리 흐름(에러 발생 시 즉시 종료) 이다.

실행 결과 예시 1 - 정상 흐름(예약 등록 → 체크인 → 룸 스케줄 조회 → 패널티 조회 → 종료)

오늘은 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
프로그램을 종료합니다.

실행 결과 예시 2 - 에러(중복 시간 예약)

오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
1

예약할 크루의 닉네임을 입력해 주세요.
빙티
룸을 입력해 주세요. (A/B/C)
A
예약 시작 시각을 입력해 주세요. (HH:mm)
19:30
예약 종료 시각을 입력해 주세요. (HH:mm)
20:30

[ERROR] 해당 시간에는 이미 예약이 존재합니다.

실행 결과 예시 3 - 에러(체크인 가능한 예약이 없음)

오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
2

체크인할 크루의 닉네임을 입력해 주세요.
쿠키
체크인할 룸을 입력해 주세요. (A/B/C)
A

[ERROR] 오늘 해당 룸에 예약이 없습니다.

실행 결과 예시 4 - 에러(시간 형식 오류)

오늘은 1월 6일 화요일입니다. 기능을 선택해 주세요.
1. 예약 등록
2. 체크인
3. 룸 스케줄 조회
4. 패널티/예약불가 크루 조회
Q. 종료
1

예약할 크루의 닉네임을 입력해 주세요.
이든
룸을 입력해 주세요. (A/B/C)
B
예약 시작 시각을 입력해 주세요. (HH:mm)
18:7a

[ERROR] 잘못된 형식을 입력하였습니다.

About

우테코 7기 최종코테 문제인 "출석"에 기반한 자체 제작 문제입니다.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages