Skip to content
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
fec3197
UserManagementService - createUser 수정
JupitorCentral Nov 25, 2025
be10ca5
사용자 생성 테스트 생성 - DB에 실제로 저장되는 persistentTest 와 @Transactional 어노테이션으로 …
JupitorCentral Nov 25, 2025
c8d1147
ReservationBookingService - book 테스트
JupitorCentral Nov 25, 2025
59250bc
ReservationBookingService - book eventProxy 선언 위치 변경
JupitorCentral Nov 25, 2025
0de0449
Seat 테이블의 status 컬럼 타입 변경 - varchar(20) 씩이나 컬럼이 클 필요가 없음.
JupitorCentral Nov 25, 2025
d7fc0e1
Reservation 테이블의 ReservationStatus 컬럼 타입 변경 - varchar(20) 씩이나 컬럼이 클 필…
JupitorCentral Nov 25, 2025
5b7c410
IllegalReservationStatusDbValueException 추가
JupitorCentral Nov 25, 2025
9f688e5
Seat 단계를 진행하는 방식 변경
JupitorCentral Nov 25, 2025
77dd612
ReservationBookingServiceIntegrationTest 테스트 변경 (setUp 단계추가), 이를 위한 S…
JupitorCentral Nov 25, 2025
2d5e51a
Foreign Constraint 에 해당하는 엔티티 필드를 읽기 전용으로 변경, F key 컬럼을 따로 설정
JupitorCentral Nov 25, 2025
3231608
일관성이 없는 변수설정 제거
JupitorCentral Nov 25, 2025
34a287f
Test method 가 하나인데 굳이 @BeforeEach 쓸 필요가 있나 ?
JupitorCentral Nov 25, 2025
fde3c7b
노출되지 말아야 할 내부 클래스 숨김
JupitorCentral Nov 25, 2025
13485af
ReservationBookingService - makeReservation 구현 변경
JupitorCentral Nov 26, 2025
18306ec
f key 코드 삭제
JupitorCentral Nov 27, 2025
69ad066
불필요 테스트 코드 삭제
JupitorCentral Nov 28, 2025
d8a57d5
테스트 h2 + embedded redis 쓰게 설정
JupitorCentral Nov 30, 2025
b918283
변수명 변경 ReservationBookingRequest.java -> ReservationRequest
JupitorCentral Nov 30, 2025
5b9ff84
Seat 관련된 Service 생성
JupitorCentral Nov 30, 2025
05dda77
SeatService 생성 (ReservationQueryService 에서 Seat 관련된 메소드 추출)
JupitorCentral Nov 30, 2025
44bf751
불필요한 ForeignKeyValidator 삭제
JupitorCentral Nov 30, 2025
056be87
SeatService - createValidSeat 테스트 추가
JupitorCentral Nov 30, 2025
af1e3b7
SeatService - createValidSeat 테스트 주석
JupitorCentral Nov 30, 2025
a63eda3
SeatService.java -> SeatManagementService.java
JupitorCentral Nov 30, 2025
0828515
Seat 생성시 일어날 수 있는 오류 추가
JupitorCentral Nov 30, 2025
9e26ddc
포맷팅
JupitorCentral Nov 30, 2025
c36aed6
주석 수정,
JupitorCentral Nov 30, 2025
3ca956b
Exception message 포맷 수정
JupitorCentral Dec 1, 2025
89db088
Reservation, Seat Enum 타입 값 수정
JupitorCentral Dec 1, 2025
a793100
Exception 의 파라미터 수정 (구현 숨기기), 테스트파일 위치 변경
JupitorCentral Dec 1, 2025
d9957a8
Seat ForeignKey 위반 클래스 재정의
JupitorCentral Dec 1, 2025
3767097
createSeat - isValidSeat 의 의미가 애매모호 한 것 같다
JupitorCentral Dec 1, 2025
d16b624
단어 통일성 ...
JupitorCentral Dec 1, 2025
83f4b50
테스트파일 위치 변경
JupitorCentral Dec 1, 2025
1be9459
Event - 티켓 가격 추가
JupitorCentral Dec 1, 2025
9bbf150
결제 service 생성 & 테스트
JupitorCentral Dec 1, 2025
8fd2946
불필요한 설정 코드 삭제
JupitorCentral Dec 2, 2025
f4432f0
InvalidStatusException.java -> InvalidReservationStatusException
JupitorCentral Dec 2, 2025
3a5243c
f key 관계에 대해, key 를 따로 저장하는것이 아니라, 엔티티 그대로 보관하는 것으로 변경
JupitorCentral Dec 4, 2025
28fc4b8
@Transactional 적용을 위해
JupitorCentral Dec 4, 2025
9938c32
객체지향화를 위한 메서드 추가
JupitorCentral Dec 4, 2025
4e37764
불필요한 변수 정의 삭제
JupitorCentral Dec 4, 2025
ad0cb21
proceed -> reserve, sell
JupitorCentral Dec 4, 2025
92b04ab
proxy 테스트 추가.
JupitorCentral Dec 4, 2025
c13f45d
테스트 버그 수정, @DisplayName 설정
JupitorCentral Dec 4, 2025
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ CLAUDE.md
.mcp.json
AGENTS.md
.codex
GEMINI.md
.gemini
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅇㄹㄴㄹㄴㅇㄹ


### Temp Files ###
cookies.txt

### Environment Variables ###
.env
gradle.properties

### Docker Compose Override ###
docker-compose.override.yml
Expand Down
7 changes: 7 additions & 0 deletions ToDoAfterCheckout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[IntelliJ Setting]

- File encoding
- Settings > Editor -> code style -> naver-coding-convention
- Settings > Tools > Actions on Save > Optimize imports, Reformat code 켜기
- 설정 파일 옮기기 (.env 등)
- Test 용 run configuration 설정하기
36 changes: 32 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ plugins {
group = "personnel.jupitorSendsme"
version = "0.0.1-SNAPSHOT"
description = "PulseTicket"
// Mockito agent 정적 로딩을 위한 변수
val mockitoAgent = configurations.create("mockitoAgent")

java {
toolchain {
Expand All @@ -28,15 +30,27 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("org.springframework.boot:spring-boot-starter-web")
// Spring Session Redis 의존성 추가
// Redis를 세션 저장소로 사용하기 위한 의존성
implementation("org.springframework.session:spring-session-data-redis")

// lombok
compileOnly("org.projectlombok:lombok")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("org.postgresql:postgresql")
annotationProcessor("org.projectlombok:lombok")
runtimeOnly("org.postgresql:postgresql")

// dev
developmentOnly("org.springframework.boot:spring-boot-devtools")

// test
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.assertj:assertj-core")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testCompileOnly("org.projectlombok:lombok")
testAnnotationProcessor("org.projectlombok:lombok")
testRuntimeOnly("com.h2database:h2")
testImplementation("com.github.codemonstur:embedded-redis:1.4.3")

// Mockito agent (Java 21+ 지원)
mockitoAgent("org.mockito:mockito-core") { isTransitive = false }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바 21을 아직 안써봐서 처음 보네요 ㅎㅎ
그런데 자바 21의 특징은 모두 파악하고 쓰시는거죠~?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맨처음엔 프로젝트 시작했을때 세련되면서 장기적으로 유지되는 안정적인 버전 써보자 해서 21을 선택했는데,
멘토님 덕분에 java 21 의 특징을 다시 한번 짚고 넘어가게 됩니다... 하하


// Argon2id 비밀번호 해싱
implementation("org.springframework.security:spring-security-crypto")
Expand All @@ -54,6 +68,20 @@ tasks.withType<JavaCompile> {
tasks.withType<Test> {
systemProperty("file.encoding", "UTF-8")
useJUnitPlatform()

// gradle.properties 값을 시스템 프로퍼티로 전달
systemProperty("TEST_POSTGRES_PORT", findProperty("TEST_POSTGRES_PORT") ?: "")
systemProperty("TEST_POSTGRES_DB", findProperty("TEST_POSTGRES_DB") ?: "")
systemProperty("TEST_POSTGRES_USER", findProperty("TEST_POSTGRES_USER") ?: "")
systemProperty("TEST_POSTGRES_PASSWORD", findProperty("TEST_POSTGRES_PASSWORD") ?: "")
systemProperty("TEST_REDIS_PORT", findProperty("TEST_REDIS_PORT") ?: "")
systemProperty("TEST_REDIS_PASSWORD", findProperty("TEST_REDIS_PASSWORD") ?: "")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KOTLIN!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 이거 intelliJ 에서 gradle 로 test 실행하려다가 환경변수 안먹길래 이렇게 두었는데,
지금은 intelliJ 에 내장된 JUnit 으로 테스트하고 있어서, 지금은 필요 없을 것 같네요... ㅇ.ㅇ


// 클래스 데이터 공유 관련 경고 방지
jvmArgs("-Xshare:off")

// Mockito agent 정적 로딩 (Java 21+ 동적 agent 로딩 경고 방지)
jvmArgs("-javaagent:${mockitoAgent.asPath}")
}

// ============================================================================
Expand Down
23 changes: 12 additions & 11 deletions db_creation_query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@
CREATE TABLE users
(
id BIGSERIAL PRIMARY KEY,
login_id VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
login_id VARCHAR(100) UNIQUE NOT NULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

길이가 부족하셨나요?? ㅋㅋ

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test login id 설정하다보니... 😂

password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);

-- EVENTS 테이블
CREATE TABLE events
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
total_seats INT NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
total_seats INT NOT NULL,
ticket_price Numeric(10, 2) NOT NULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent가 변경되니 딱 수정된 부분만 찾기가 어렵네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이게 말씀해주신 Naver 핵데이 코딩 컨벤션 적용했던게 여기에도 적용되다보니 이렇게 됬네요.
intelliJ 에서 저장할때마다 수정하라고 되어 있어서.. 근데 java 인데 여기에도 적용됬네요 -_-;; 음 수정해야겠네요

created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL
);

-- SEATS 테이블
Expand All @@ -27,7 +28,7 @@ CREATE TABLE seats
id BIGSERIAL PRIMARY KEY,
event_id BIGINT NOT NULL, -- FK -> events.id
seat_number INT NOT NULL,
status VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL, -- AVAILABLE, RESERVED, SOLD
reserved_until TIMESTAMP NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
Expand All @@ -41,7 +42,7 @@ CREATE TABLE reservations
user_id BIGINT NOT NULL, -- FK -> users.id
seat_id BIGINT NOT NULL, -- FK -> seats.id
event_id BIGINT NOT NULL, -- FK -> events.id
status VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL, -- PENDING, CONFIRMED, CANCELLED, EXPIRED
expires_at TIMESTAMP NOT NULL,
confirmed_at TIMESTAMP NULL,
cancelled_at TIMESTAMP NULL,
Expand Down
9 changes: 0 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,20 @@ services:
env_file:
- .env
environment:
# 로케일 설정
PGDATA: /var/lib/postgresql/data/pgdata
ports:
# 호스트 포트:컨테이너 포트 (docker-compose.override.yml에서 설정)
- "${POSTGRES_HOST_PORT:-5432}:${POSTGRES_PORT:-5432}"
volumes:
# 데이터 영속성을 위한 볼륨 마운트
- postgres_data:/var/lib/postgresql/data
# 초기화 스크립트 마운트
- ./docker/postgres/init:/docker-entrypoint-initdb.d
networks:
- pulseticket-network
healthcheck:
# 데이터베이스 준비 상태 확인
test: [ "CMD-SHELL", "pg_isready -h localhost -p ${POSTGRES_PORT:-5432} -U ${POSTGRES_USER} -d ${POSTGRES_DB}" ]
interval: 10s
timeout: 5s
retries: 5
labels:
# Promtail이 이 컨테이너의 로그를 수집하도록 설정
logging: "promtail"
logging_jobname: "pulseticket-postgres"
restart: unless-stopped
Expand All @@ -56,7 +50,6 @@ services:
# 호스트 포트:컨테이너 포트 (docker-compose.override.yml에서 설정)
- "${REDIS_HOST_PORT:-6379}:${REDIS_PORT:-6379}"
volumes:
# 데이터 영속성을 위한 볼륨 마운트
- redis_data:/data
networks:
- pulseticket-network
Expand Down Expand Up @@ -191,15 +184,13 @@ services:

# ============================================================================
# 네트워크 설정
# 서비스 간 통신을 위한 내부 네트워크 생성
# ============================================================================
networks:
pulseticket-network:
driver: bridge

# ============================================================================
# 볼륨 설정
# 데이터 영속성을 위한 볼륨 정의
# ============================================================================
volumes:
postgres_data:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import personnel.jupitorsendsme.pulseticket.dto.ReservationBookingRequest;
import personnel.jupitorsendsme.pulseticket.dto.ReservationBookingResponse;
import personnel.jupitorsendsme.pulseticket.dto.ReservationRequest;
import personnel.jupitorsendsme.pulseticket.service.ReservationBookingService;

/**
Expand All @@ -30,7 +30,7 @@ public class ReservationBookingController {
* @return 예약 성공 여부를 포함한 예약 관련 정보
*/
@PostMapping
ReservationBookingResponse booking(@RequestBody ReservationBookingRequest request) {
ReservationBookingResponse booking(@RequestBody ReservationRequest request) {
return reservationBookingService.book(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import personnel.jupitorsendsme.pulseticket.dto.ReservationBookingRequest;
import personnel.jupitorsendsme.pulseticket.dto.ReservationQueryResponse;
import personnel.jupitorsendsme.pulseticket.dto.ReservationRequest;
import personnel.jupitorsendsme.pulseticket.entity.SeatStatusResponse;
import personnel.jupitorsendsme.pulseticket.service.ReservationQueryService;
import personnel.jupitorsendsme.pulseticket.service.SeatManagementService;

/**
* 좌석 조회 컨트롤러
Expand All @@ -24,6 +25,7 @@
public class ReservationQueryController {

private final ReservationQueryService reservationQueryService;
private final SeatManagementService seatManagementService;

/**
* 특정 이벤트에 대한 예약 가능 여부. <br>
Expand All @@ -32,7 +34,7 @@ public class ReservationQueryController {
* @return 예약 가능 여부
*/
@GetMapping("isBookingEventAvailable")
public Boolean isBookingEventAvailable(@ModelAttribute ReservationBookingRequest request) {
public Boolean isBookingEventAvailable(@ModelAttribute ReservationRequest request) {
return reservationQueryService.isBookingEventAvailable(request);
}

Expand All @@ -42,8 +44,8 @@ public Boolean isBookingEventAvailable(@ModelAttribute ReservationBookingRequest
* @return 특정 이벤트의 좌석 정보 리스트
*/
@GetMapping("statusOfSeatsOfTheEvent")
public List<SeatStatusResponse> statusOfSeatsOfTheEvent(@ModelAttribute ReservationBookingRequest request) {
return reservationQueryService.statusOfSeatsOfTheEvent(request);
public List<SeatStatusResponse> statusOfSeatsOfTheEvent(@ModelAttribute ReservationRequest request) {
return seatManagementService.statusOfSeatsOfTheEvent(request);
}

/**
Expand All @@ -53,8 +55,8 @@ public List<SeatStatusResponse> statusOfSeatsOfTheEvent(@ModelAttribute Reservat
*/

@GetMapping("isSpecificSeatAvailable")
public Boolean isSpecificSeatAvailable(@ModelAttribute ReservationBookingRequest request) {
return reservationQueryService.isSpecificSeatAvailable(request);
public Boolean isSpecificSeatAvailable(@ModelAttribute ReservationRequest request) {
return seatManagementService.isSpecificSeatAvailable(request);
}

/**
Expand All @@ -63,7 +65,7 @@ public Boolean isSpecificSeatAvailable(@ModelAttribute ReservationBookingRequest
* @return 예약 목록이 담긴 DTO
*/
@GetMapping("inquiryUserReservations")
public List<ReservationQueryResponse> inquiryUserReservations(@ModelAttribute ReservationBookingRequest request) {
public List<ReservationQueryResponse> inquiryUserReservations(@ModelAttribute ReservationRequest request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ModelAttribute 가 왜 필요한가요?? 그냥 지나갔네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 그냥 필요없었는데 이 파라미터는 url 값이 객체에 전달된다 라는걸 좀 뭔가 표현하려고 했었던 것 같아요 저때는. 하지만 less code less bug 니까, 지우는게 좋아보이네요 ㅎㅎ

return reservationQueryService.inquiryUserReservations(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import personnel.jupitorsendsme.pulseticket.dto.ReservationBookingRequest;
import personnel.jupitorsendsme.pulseticket.dto.ReservationRequest;
import personnel.jupitorsendsme.pulseticket.service.UserManagementService;

/**
Expand All @@ -22,17 +22,17 @@ public class UserManagementController {
private final UserManagementService userManagementService;

@GetMapping("isUserPresent")
Boolean isUserPresent(@ModelAttribute ReservationBookingRequest request) {
Boolean isUserPresent(@ModelAttribute ReservationRequest request) {
return userManagementService.isUserPresent(request);
}

@PostMapping("registerUser")
Boolean registerUser(@RequestBody ReservationBookingRequest request) {
Boolean registerUser(@RequestBody ReservationRequest request) {
return userManagementService.registerUser(request);
}

@PostMapping("isUserValid")
Boolean isUserValid(@RequestBody ReservationBookingRequest request) {
Boolean isUserValid(@RequestBody ReservationRequest request) {
return userManagementService.isUserValid(request);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package personnel.jupitorsendsme.pulseticket.dto;

import java.math.BigDecimal;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
Expand All @@ -9,8 +13,10 @@
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
public class ReservationBookingRequest {
@AllArgsConstructor
public class ReservationRequest {
/**
* 예약신청자 로그인 ID
*/
Expand All @@ -30,4 +36,14 @@ public class ReservationBookingRequest {
* 예약하고자 하는 시트 번호
*/
private Integer seatNumber;

/**
* 예약 고유 번호
*/
private Long reservationId;

/**
* 결제 금액
*/
private BigDecimal paymentAmount;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package personnel.jupitorsendsme.pulseticket.entity;

import java.math.BigDecimal;
import java.util.List;

import jakarta.persistence.Column;
Expand Down Expand Up @@ -48,4 +49,10 @@ public class Event extends BaseEntity {
*/
@OneToMany(mappedBy = "event")
private List<Seat> seats;

/**
* 티켓 가격
*/
@Column(name = "ticket_price", nullable = false)
private BigDecimal ticketPrice;
}
Loading