Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Flooding Server V2

학생을 위한 학교 편의 플랫폼 백엔드 서버입니다.

기숙사 신청(자습실, 안마의자), 급식 조회, 동아리 관리, 시간표, AI 기반 음악 추천 등 다양한 편의 기능을 제공합니다.

---

## 기술 스택

| 분류 | 기술 |
|------|------|
| 언어 | Kotlin, Java 24 |
| 프레임워크 | Spring Boot 4.0.2 |
| 데이터베이스 | PostgreSQL, Redis |
| 보안 | Spring Security, JWT |
| 인프라 | Docker, Harbor, Kubernetes (Helm) |
| 빌드 | Gradle KTS |
| 문서 | SpringDoc OpenAPI (Swagger) |
| 테스트 | Kotest, MockK |

---

## 주요 기능

- **동아리** — 동아리 CRUD, 동아리 지원서 제출 및 승인, 동아리 개설 신청
- **기숙사 - 자습실** — 자습실 신청 및 목록 조회, SSE 실시간 알림
- **기숙사 - 안마의자** — 안마의자 신청 및 목록 조회
- **기숙사 - 기상음악** — 기상음악 신청 (URL / 직접 업로드)
- **기숙사 - 벌점** — 벌점 부여 및 조회
- **기숙사 - 청소구역** — 청소구역 생성 및 구성원 배정
- **급식 / 시간표** — NEIS API 연동으로 급식·시간표 조회
- **AI** — AI 채팅 및 노래 추천

---
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class ApplyMassageServiceImpl(

val now = LocalTime.now()

if (now.isBefore(massageProperties.openTime)) {
throw ExpectedException("안마의자 신청 시간이 아닙니다.", HttpStatus.BAD_REQUEST)
}
if (now.isBefore(massageProperties.openTime)) {
throw ExpectedException("안마의자 신청 시간이 아닙니다.", HttpStatus.BAD_REQUEST)
}

val lock = redissonClient.getLock(massageProperties.lockKey)
val acquired = lock.tryLock(5, 3, TimeUnit.SECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,15 @@ class StudyApplicationServiceImpl(
}

if (outOfRange) {
log.warn("자습 신청 가능 시간 아님: userId={}, now={}, openTime={}, closeTime={}", user.id, now, studyProperties.openTime, studyProperties.closeTime)
throw ExpectedException("자습 신청 시간이 아닙니다.", HttpStatus.BAD_REQUEST) }
log.warn(
"자습 신청 가능 시간 아님: userId={}, now={}, openTime={}, closeTime={}",
user.id,
now,
studyProperties.openTime,
studyProperties.closeTime,
)
throw ExpectedException("자습 신청 시간이 아닙니다.", HttpStatus.BAD_REQUEST)
}

if (studyRedisAdapter.getApplicationStatus(user.id) == StudyApplicationStatus.BANNED ||
studyBanJpaRepository.existsByUserIdAndBannedUntilAfter(user.id, LocalDateTime.now(clock))
Expand Down
Loading