3.6 KiB
3.6 KiB
course-registration
Spring Boot 4.1.1 / Java 21 기반 수강신청 API 예제입니다. 핵심은 CRUD 개수보다 수강신청 거부 규칙(R1~R8) 과 동시 신청 시 정원·학점·시간표 정확성을 지키는 것입니다.
Scope
- 수강신청(Create)
- 내 수강신청 목록 / 강의 목록·상세(Read)
- 수강취소(Delete, soft cancel)
- 신청 수정(Update) API 없음 — 취소 후 재신청
- 마스터 데이터 CRUD 없음 — Seeder 사용
- 인증/JWT 없음
- k6 부하 테스트는 후속 범위
상세 규칙은 docs/Requirements.md를 기준으로 합니다.
Run local
./gradlew bootRun
기본 profile은 local이며 H2 + Seeder가 자동 활성화됩니다.
- API:
http://127.0.0.1:8080/api/v1 - Swagger UI:
http://127.0.0.1:8080/swagger-ui.html - OpenAPI JSON:
http://127.0.0.1:8080/v3/api-docs - Health:
http://127.0.0.1:8080/actuator/health - H2 console:
http://127.0.0.1:8080/h2-console
Run dev with PostgreSQL
cp .env.example .env
# 필요한 값 수정
docker compose up --build
Compose는 host에 127.0.0.1로만 노출합니다.
docker compose down
# DB volume까지 초기화하려면
docker compose down -v
Profiles
| profile | DB | ddl-auto | Seeder | Swagger |
|---|---|---|---|---|
| local | H2 | create-drop | ON | ON |
| dev | PostgreSQL | update | APP_SEED_ENABLED |
ON |
| prod | PostgreSQL | validate | OFF | SWAGGER_ENABLED 기본 false |
운영 profile의 DB 접속 정보는 반드시 환경변수로 주입합니다.
API
POST /api/v1/users/{userId}/registrations
GET /api/v1/users/{userId}/registrations?semesterId={semesterId}
DELETE /api/v1/users/{userId}/registrations/{registrationId}
GET /api/v1/lessons?semesterId={id}&subjectId={id}&page=0&size=20
GET /api/v1/lessons/{lessonId}
Concurrency invariant
모든 registration mutation은 아래 순서로 row lock을 획득합니다.
User FOR UPDATE
-> Lesson FOR UPDATE
-> R4~R8 검증
-> INSERT / cancel
User lock은 동일 학생의 학점·동일과목·시간표 경쟁을 직렬화하고, Lesson lock은 정원 경쟁을 직렬화합니다. 락 순서는 항상 User -> Lesson으로 고정합니다.
Local seed IDs
Postman과 동일한 고정 ID를 사용합니다.
Semester
00000000-0000-0000-0000-000000000001
1학년 학생
30000000-0000-0000-0000-000000000001
2학년 학생
30000000-0000-0000-0000-000000000002
대학원생
30000000-0000-0000-0000-000000000003
자료구조 01분반
40000000-0000-0000-0000-000000000001
자료구조 02분반 (동일 Subject)
40000000-0000-0000-0000-000000000002
운영체제 (자료구조 01과 월요일 시간 충돌)
40000000-0000-0000-0000-000000000003
정원 1명 강의
40000000-0000-0000-0000-000000000004
최소 3학년 강의
40000000-0000-0000-0000-000000000005
대학원생 전용 강의
40000000-0000-0000-0000-000000000006
월요일 11:00~13:00 경계 테스트 강의
40000000-0000-0000-0000-000000000007
Postman
postman/
course-registration.postman_collection.json
local.postman_environment.json
dev.postman_environment.json
Register lesson 요청은 성공 시 응답의 registrationId를 environment에 자동 저장합니다.
Tests
./gradlew test
./gradlew build
테스트에는 다음이 포함됩니다.
- R1~R8 규칙 및 경계값
- 신청/조회/취소/재신청
- 취소 이력 유지
- 정원 1명에 동시 10명
- 정원 30명에 동시 50명
- 동일 학생의 학점 한도 경쟁
- 동일 학생의 시간표 충돌 경쟁
- 동일 학생의 같은 강의 중복 경쟁