-
Notifications
You must be signed in to change notification settings - Fork 1
feat: 행사 API 추가 #534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat: 행사 API 추가 #534
Changes from all commits
6a608bd
3ebb307
8af3c20
21c18ac
59fc3dc
79e71c6
e7057a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package gg.agit.konect.domain.event.controller; | ||
|
|
||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
|
|
||
| import gg.agit.konect.domain.event.dto.EventBoothMapResponse; | ||
| import gg.agit.konect.domain.event.dto.EventBoothsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventContentsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventHomeResponse; | ||
| import gg.agit.konect.domain.event.dto.EventMiniEventsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventProgramsResponse; | ||
| import gg.agit.konect.domain.event.enums.EventProgramType; | ||
| import gg.agit.konect.global.auth.annotation.UserId; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import jakarta.validation.constraints.Min; | ||
|
|
||
| @Tag(name = "(Normal) Event: 행사", description = "행사 API") | ||
| @RequestMapping("/events") | ||
| public interface EventApi { | ||
|
|
||
| @Operation(summary = "행사 홈 정보를 조회한다.") | ||
| @GetMapping("/{eventId}/home") | ||
| ResponseEntity<EventHomeResponse> getEventHome( | ||
| @PathVariable Integer eventId, | ||
| @UserId Integer userId | ||
| ); | ||
|
|
||
| @Operation(summary = "행사 프로그램 목록을 조회한다.") | ||
| @GetMapping("/{eventId}/programs") | ||
| ResponseEntity<EventProgramsResponse> getEventPrograms( | ||
| @PathVariable Integer eventId, | ||
| @RequestParam(defaultValue = "ALL") EventProgramType type, | ||
| @RequestParam(defaultValue = "1") @Min(1) Integer page, | ||
| @RequestParam(defaultValue = "20") @Min(1) Integer limit, | ||
| @UserId Integer userId | ||
| ); | ||
|
|
||
| @Operation(summary = "행사 부스 목록을 조회한다.") | ||
| @GetMapping("/{eventId}/booths") | ||
| ResponseEntity<EventBoothsResponse> getEventBooths( | ||
| @PathVariable Integer eventId, | ||
| @RequestParam(required = false) String category, | ||
| @RequestParam(required = false) String keyword, | ||
| @RequestParam(defaultValue = "1") @Min(1) Integer page, | ||
| @RequestParam(defaultValue = "20") @Min(1) Integer limit | ||
| ); | ||
|
|
||
| @Operation(summary = "행사 부스 맵을 조회한다.") | ||
| @GetMapping("/{eventId}/booth-map") | ||
| ResponseEntity<EventBoothMapResponse> getEventBoothMap( | ||
| @PathVariable Integer eventId | ||
| ); | ||
|
|
||
| @Operation(summary = "행사 미니 이벤트 목록을 조회한다.") | ||
| @GetMapping("/{eventId}/mini-events") | ||
| ResponseEntity<EventMiniEventsResponse> getEventMiniEvents( | ||
| @PathVariable Integer eventId, | ||
| @RequestParam(defaultValue = "1") @Min(1) Integer page, | ||
| @RequestParam(defaultValue = "20") @Min(1) Integer limit, | ||
| @UserId Integer userId | ||
| ); | ||
|
|
||
| @Operation(summary = "행사 콘텐츠 목록을 조회한다.") | ||
| @GetMapping("/{eventId}/contents") | ||
| ResponseEntity<EventContentsResponse> getEventContents( | ||
| @PathVariable Integer eventId, | ||
| @RequestParam(required = false) String category, | ||
| @RequestParam(defaultValue = "1") @Min(1) Integer page, | ||
| @RequestParam(defaultValue = "20") @Min(1) Integer limit | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package gg.agit.konect.domain.event.controller; | ||
|
|
||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.validation.annotation.Validated; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import gg.agit.konect.domain.event.dto.EventBoothMapResponse; | ||
| import gg.agit.konect.domain.event.dto.EventBoothsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventContentsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventHomeResponse; | ||
| import gg.agit.konect.domain.event.dto.EventMiniEventsResponse; | ||
| import gg.agit.konect.domain.event.dto.EventProgramsResponse; | ||
| import gg.agit.konect.domain.event.enums.EventProgramType; | ||
| import gg.agit.konect.domain.event.service.EventService; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @RestController | ||
| @Validated | ||
| @RequiredArgsConstructor | ||
| public class EventController implements EventApi { | ||
|
|
||
| private final EventService eventService; | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventHomeResponse> getEventHome(Integer eventId, Integer userId) { | ||
| return ResponseEntity.ok(eventService.getEventHome(eventId, userId)); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventProgramsResponse> getEventPrograms(Integer eventId, EventProgramType type, Integer page, | ||
| Integer limit, | ||
| Integer userId) { | ||
| return ResponseEntity.ok(eventService.getEventPrograms(eventId, type, page, limit, userId)); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventBoothsResponse> getEventBooths(Integer eventId, String category, String keyword, | ||
| Integer page, Integer limit) { | ||
| return ResponseEntity.ok(eventService.getEventBooths(eventId, category, keyword, page, limit)); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventBoothMapResponse> getEventBoothMap(Integer eventId) { | ||
| return ResponseEntity.ok(eventService.getEventBoothMap(eventId)); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventMiniEventsResponse> getEventMiniEvents(Integer eventId, Integer page, Integer limit, | ||
| Integer userId) { | ||
| return ResponseEntity.ok(eventService.getEventMiniEvents(eventId, page, limit, userId)); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<EventContentsResponse> getEventContents(Integer eventId, String category, Integer page, | ||
| Integer limit) { | ||
| return ResponseEntity.ok(eventService.getEventContents(eventId, category, page, limit)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record EventBoothMapResponse( | ||
| String mapImageUrl, | ||
| List<ZoneResponse> zones, | ||
| List<BoothMapItemResponse> booths | ||
| ) { | ||
|
|
||
| public record ZoneResponse( | ||
| String code, | ||
| String label | ||
| ) { | ||
| } | ||
|
|
||
| public record BoothMapItemResponse( | ||
| Integer boothId, | ||
| String name, | ||
| String zone, | ||
| Integer x, | ||
| Integer y, | ||
| Integer width, | ||
| Integer height, | ||
| String status | ||
| ) { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| public record EventBoothSummaryResponse( | ||
| Integer boothId, | ||
| String name, | ||
| String category, | ||
| String locationLabel, | ||
| String zone, | ||
| String thumbnailUrl, | ||
| boolean open | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record EventBoothsResponse( | ||
| Long totalCount, | ||
| Integer currentCount, | ||
| Integer totalPage, | ||
| Integer currentPage, | ||
| List<EventBoothSummaryResponse> booths | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| public record EventContentSummaryResponse( | ||
| Integer contentId, | ||
| String title, | ||
| String thumbnailUrl, | ||
| String type, | ||
| String summary, | ||
| LocalDateTime publishedAt | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record EventContentsResponse( | ||
| Long totalCount, | ||
| Integer currentCount, | ||
| Integer totalPage, | ||
| Integer currentPage, | ||
| List<EventContentSummaryResponse> contents | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| public record EventHomeResponse( | ||
| Integer eventId, | ||
| String title, | ||
| String subtitle, | ||
| String posterImageUrl, | ||
| LocalDateTime startAt, | ||
| LocalDateTime endAt, | ||
| String notice, | ||
| Summary summary, | ||
| UserStatus userStatus | ||
| ) { | ||
|
|
||
| public record Summary( | ||
| Integer programCount, | ||
| Integer boothCount, | ||
| Integer eventCount, | ||
| Integer contentCount | ||
| ) { | ||
| } | ||
|
|
||
| public record UserStatus( | ||
| Integer point, | ||
| Integer participatedEventCount | ||
| ) { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| public record EventMiniEventSummaryResponse( | ||
| Integer miniEventId, | ||
| String title, | ||
| String thumbnailUrl, | ||
| String description, | ||
| String reward, | ||
| String status, | ||
| boolean joined | ||
| ) { | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public record EventMiniEventsResponse( | ||
| Long totalCount, | ||
| Integer currentCount, | ||
| Integer totalPage, | ||
| Integer currentPage, | ||
| List<EventMiniEventSummaryResponse> miniEvents | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| public record EventProgramSummaryResponse( | ||
| Integer programId, | ||
| String title, | ||
| String description, | ||
| String thumbnailUrl, | ||
| Integer rewardPoint, | ||
| String status, | ||
| boolean participated | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package gg.agit.konect.domain.event.dto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import gg.agit.konect.domain.event.enums.EventProgramType; | ||
|
|
||
| public record EventProgramsResponse( | ||
| Long totalCount, | ||
| Integer currentCount, | ||
| Integer totalPage, | ||
| Integer currentPage, | ||
| EventProgramType type, | ||
| List<EventProgramSummaryResponse> programs | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gg.agit.konect.domain.event.enums; | ||
|
|
||
| public enum EventBoothMapItemStatus { | ||
| OPEN, | ||
| CLOSED, | ||
| HIDDEN | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gg.agit.konect.domain.event.enums; | ||
|
|
||
| public enum EventContentType { | ||
| ARTICLE, | ||
| IMAGE, | ||
| VIDEO | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gg.agit.konect.domain.event.enums; | ||
|
|
||
| public enum EventProgramType { | ||
| ALL, | ||
| POINT, | ||
| RESONANCE | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gg.agit.konect.domain.event.enums; | ||
|
|
||
| public enum EventProgressStatus { | ||
| UPCOMING, | ||
| ONGOING, | ||
| ENDED | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package gg.agit.konect.domain.event.enums; | ||
|
|
||
| public enum EventStatus { | ||
| DRAFT, | ||
| PUBLISHED, | ||
| ENDED | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package gg.agit.konect.domain.event.model; | ||
|
|
||
| import static jakarta.persistence.GenerationType.IDENTITY; | ||
| import static lombok.AccessLevel.PROTECTED; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| import gg.agit.konect.domain.event.enums.EventStatus; | ||
| import gg.agit.konect.global.model.BaseEntity; | ||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Entity; | ||
| import jakarta.persistence.EnumType; | ||
| import jakarta.persistence.Enumerated; | ||
| import jakarta.persistence.GeneratedValue; | ||
| import jakarta.persistence.Id; | ||
| import jakarta.persistence.Table; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| @Getter | ||
| @Entity | ||
| @Table(name = "event") | ||
| @NoArgsConstructor(access = PROTECTED) | ||
| public class Event extends BaseEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = IDENTITY) | ||
| @Column(name = "id", nullable = false, updatable = false, unique = true) | ||
| private Integer id; | ||
|
|
||
| @Column(name = "title", nullable = false, length = 100) | ||
| private String title; | ||
|
|
||
| @Column(name = "subtitle", length = 255) | ||
| private String subtitle; | ||
|
|
||
| @Column(name = "poster_image_url", length = 255) | ||
| private String posterImageUrl; | ||
|
|
||
| @Column(name = "notice", columnDefinition = "TEXT") | ||
| private String notice; | ||
|
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [LEVEL: high] 🤖 Prompt for AI Agents |
||
|
|
||
| @Column(name = "start_at", nullable = false) | ||
| private LocalDateTime startAt; | ||
|
|
||
| @Column(name = "end_at", nullable = false) | ||
| private LocalDateTime endAt; | ||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(name = "status", nullable = false, length = 20) | ||
| private EventStatus status; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[LEVEL: medium] Line 10의
joined값이 현재 구현에서 상수로 고정되어 응답 의미가 깨집니다.문제:
src/main/java/gg/agit/konect/domain/event/service/EventService.javaLine 241-251에서EventMiniEventSummaryResponse.joined에 항상false를 주입해 DTO가 사용자 참여 상태를 표현하지 못합니다.영향: 실제 참여 사용자도 미참여로 내려가 버튼 상태/UX가 잘못될 수 있습니다.
제안: 참여 여부를 사용자 기준으로 조회해 채우거나, 기능 미지원 단계라면
joined를 nullable로 변경(또는 필드 제거)해 오해를 방지하세요. As per coding guidelines, "확장성: 새 요구사항 추가 시 변경 범위가 최소화되는 구조인지(하드코딩 분기/값 여부 포함) 점검한다."🤖 Prompt for AI Agents