-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/#45 광고 DB 구조 및 프로젝트 구조 #46
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
Changes from all commits
9c4e738
dd13666
b8a88b5
94e465e
15cbf5e
eef418b
0625609
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,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.application.dto.request; | ||
|
|
||
| public class AdvertisementRequest { | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.application.dto.response; | ||
|
|
||
| public class AdvertisementResponse { | ||
| // TODO: 대시보드 공통 응답값 정의 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.application.mapper; | ||
|
|
||
| public class AdvertisementConverter { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.domain.constant; | ||
|
|
||
| public enum Grain { | ||
| HOURLY, DAILY | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.domain.constant; | ||
|
|
||
| public enum Provider { | ||
| GOOGLE, KAKAO, NAVER | ||
| // 추후 값 추가 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.domain.service; | ||
|
|
||
| public interface AdvertisementQueryService { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.domain.service; | ||
|
|
||
| import lombok.AccessLevel; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| @Transactional(readOnly = true) | ||
| @RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class AdvertisementQueryServiceImpl implements AdvertisementQueryService{ | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.exception; | ||
|
|
||
| import com.whereyouad.WhereYouAd.global.exception.AppException; | ||
| import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; | ||
|
|
||
| public class AdvertisementException extends AppException { | ||
| public AdvertisementException(BaseErrorCode code) { | ||
| super(code); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.exception.code; | ||
|
|
||
| import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public enum AdvertisementErrorCode implements BaseErrorCode { | ||
|
|
||
| // TODO: 에러 코드 추가 | ||
| ; | ||
|
|
||
| private final HttpStatus httpStatus; | ||
| private final String code; | ||
| private final String message; | ||
|
Comment on lines
+10
to
+17
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. 광고 도메인 에러코드가 비어 있어 예외 표준화가 동작하지 않습니다.
🔧 제안 수정안 public enum AdvertisementErrorCode implements BaseErrorCode {
-
- // TODO: 에러 코드 추가
- ;
+ ADVERTISEMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "ADVERTISEMENT_404", "광고를 찾을 수 없습니다."),
+ ADVERTISEMENT_BAD_REQUEST(HttpStatus.BAD_REQUEST, "ADVERTISEMENT_400", "잘못된 광고 요청입니다."),
+ ADVERTISEMENT_FORBIDDEN(HttpStatus.FORBIDDEN, "ADVERTISEMENT_403", "광고 접근 권한이 없습니다.");
private final HttpStatus httpStatus;
private final String code;
private final String message;
}As per coding guidelines 🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.persistence.entity; | ||
|
|
||
| import com.whereyouad.WhereYouAd.domains.advertisement.domain.constant.Provider; | ||
| import com.whereyouad.WhereYouAd.global.common.BaseEntity; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Table(name = "advertisement") | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @AllArgsConstructor | ||
| @Builder | ||
| public class Advertisement extends BaseEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "ad_id") | ||
| private Long id; | ||
|
Comment on lines
+16
to
+21
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. 외부 광고 플랫폼의 고유 ID( 현재 예를 들어 Google Ads API는 각 광고에 고유한 + `@Column`(name = "external_ad_id", nullable = false)
+ private String externalAdId; // 외부 플랫폼(Google/Kakao/Naver)에서 부여한 광고 ID🤖 Prompt for AI Agents |
||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(name = "provider", nullable = false) | ||
| private Provider provider; | ||
|
|
||
| private LocalDateTime startDate; | ||
|
|
||
| private LocalDateTime endDate; | ||
|
|
||
| // @Enumerated(EnumType.STRING) | ||
| // @Column(name = "status", nullable = false) | ||
| // @ColumnDefault("'ON_GOING'") | ||
| // AdStatus 는 ON_GOING, PAUSED, OVER 가 존재 | ||
| // join 연산으로 인한 성능 저하 우려 -> 일단은 주석 처리 | ||
| // private AdStatus adStatus; | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||
| package com.whereyouad.WhereYouAd.domains.advertisement.persistence.entity; | ||||||||||
|
|
||||||||||
| import com.whereyouad.WhereYouAd.domains.advertisement.domain.constant.Grain; | ||||||||||
| import com.whereyouad.WhereYouAd.domains.advertisement.domain.constant.Provider; | ||||||||||
| import com.whereyouad.WhereYouAd.domains.project.persistence.entity.Project; | ||||||||||
| import com.whereyouad.WhereYouAd.global.common.BaseEntity; | ||||||||||
| import jakarta.persistence.*; | ||||||||||
| import lombok.*; | ||||||||||
|
|
||||||||||
| import java.math.BigDecimal; | ||||||||||
| import java.time.LocalDateTime; | ||||||||||
|
|
||||||||||
| @Entity | ||||||||||
| @Getter | ||||||||||
| @Table(name = "metric_fact") | ||||||||||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||||||||||
| @AllArgsConstructor | ||||||||||
| @Builder | ||||||||||
| public class MetricFact extends BaseEntity { | ||||||||||
|
|
||||||||||
| @Id | ||||||||||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||||||
| @Column(name = "metric_fact_id") | ||||||||||
| private Long id; | ||||||||||
|
|
||||||||||
| @Enumerated(EnumType.STRING) | ||||||||||
| @Column(name = "grain", nullable = false) | ||||||||||
| private Grain grain; // 집계 단위(HOURLY, DAILY) | ||||||||||
|
|
||||||||||
| @Column(name = "time_bucket", nullable = false) | ||||||||||
| private LocalDateTime timeBucket; // 집계 단위 시작 시간 | ||||||||||
|
Comment on lines
+30
to
+31
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. 🧩 Analysis chain🏁 Script executed: # 먼저 MetricFact.java 파일 확인
find . -name "MetricFact.java" -type f | head -5Repository: WhereYouAd/WhereYouAd-Backend Length of output: 171 🏁 Script executed: # Java 파일 구조 파악
git ls-files "src/main/java/com/whereyouad/WhereYouAd/domains/advertisement/persistence/entity/"Repository: WhereYouAd/WhereYouAd-Backend Length of output: 169 🏁 Script executed: # 전체 파일 목록으로 경로 확인
fd -t f "MetricFact.java"Repository: WhereYouAd/WhereYouAd-Backend Length of output: 169 🏁 Script executed: # MetricFact.java 파일 내용 확인
cat -n src/main/java/com/whereyouad/WhereYouAd/domains/advertisement/persistence/entity/MetricFact.javaRepository: WhereYouAd/WhereYouAd-Backend Length of output: 2201 🏁 Script executed: # 다른 엔티티에서 LocalDateTime 또는 Instant 사용 패턴 확인
rg "private (LocalDateTime|Instant)" src/main/java/com/whereyouad/WhereYouAd/domains/advertisement/persistence/entity/ -A 2Repository: WhereYouAd/WhereYouAd-Backend Length of output: 456 🏁 Script executed: # application.properties 또는 application.yml 파일 확인 (현재 설정 상태)
find . -name "application*.yml" -o -name "application*.properties" | head -10Repository: WhereYouAd/WhereYouAd-Backend Length of output: 109 🏁 Script executed: # application.yml 파일 내용 확인
cat -n ./src/main/resources/application.ymlRepository: WhereYouAd/WhereYouAd-Backend Length of output: 3899 🏁 Script executed: # BaseEntity 확인 (createdAt, updatedAt 등이 어떻게 정의되어 있는지)
find . -name "BaseEntity.java" -type fRepository: WhereYouAd/WhereYouAd-Backend Length of output: 144 🏁 Script executed: # 코드베이스에서 Instant 사용 여부 확인
rg "import java.time.Instant" src/main/java/ -l | head -10Repository: WhereYouAd/WhereYouAd-Backend Length of output: 55 🏁 Script executed: # Spring Boot 버전 확인
find . -name "pom.xml" -o -name "build.gradle" | head -3Repository: WhereYouAd/WhereYouAd-Backend Length of output: 87 🏁 Script executed: # BaseEntity 파일 내용 확인
cat -n ./src/main/java/com/whereyouad/WhereYouAd/global/common/BaseEntity.javaRepository: WhereYouAd/WhereYouAd-Backend Length of output: 1002 🏁 Script executed: # build.gradle에서 Spring Boot 버전 확인
cat -n ./build.gradle | head -30Repository: WhereYouAd/WhereYouAd-Backend Length of output: 856 🏁 Script executed: # 코드베이스에서 타임존 관련 설정이 있는지 확인
rg "timezone|TimeZone|UTC" src/main/java/ -iRepository: WhereYouAd/WhereYouAd-Backend Length of output: 375 🏁 Script executed: # LocalDateTime이 다른 엔티티에서도 사용되고 있는지 확인
rg "private LocalDateTime" src/main/java/com/whereyouad/WhereYouAd/domains/ --type javaRepository: WhereYouAd/WhereYouAd-Backend Length of output: 496 🏁 Script executed: # MySQL TIMESTAMP 타입의 타임존 처리 확인 및 Spring Boot 3.5.9 호환성 검증
cat build.gradle | grep -A 20 "dependencies"Repository: WhereYouAd/WhereYouAd-Backend Length of output: 835 🏁 Script executed: # 기존 데이터 구조 확인: DB 스키마에서 time_bucket이 어떤 타입인지
rg "CREATE TABLE|time_bucket" src/ --type javaRepository: WhereYouAd/WhereYouAd-Backend Length of output: 221 팩트 테이블의 시간 컬럼으로
⏱️ 권장 수정 — Instant 사용-import java.time.LocalDateTime;
+import java.time.Instant;
- `@Column`(name = "time_bucket", nullable = false)
- private LocalDateTime timeBucket; // 집계 단위 시작 시간
+ `@Column`(name = "time_bucket", nullable = false)
+ private Instant timeBucket; // 집계 단위 시작 시간 (UTC 기준)그리고 spring:
jpa:
properties:
hibernate:
jdbc:
time_zone: UTC참고: 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| // @Column(name = "dimension_type") | ||||||||||
| // private String dimensionType; | ||||||||||
|
Comment on lines
+33
to
+34
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. 주석 처리된 PR 설명에서 🗑️ 제거 예시-// `@Column`(name = "dimension_type")
-// private String dimensionType;
-📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| @Column(name = "impressions") | ||||||||||
| private Long impressions; // 노출수 | ||||||||||
|
|
||||||||||
| @Column(name = "clicks") | ||||||||||
| private Long clicks; // 클릭수 | ||||||||||
|
|
||||||||||
| @Column(name = "conversions") | ||||||||||
| private Long conversions; // 전환수 | ||||||||||
|
Comment on lines
+36
to
+43
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. 팩트 테이블의 수치 컬럼은
현재 설계에서 집계 쿼리( 🛡️ 제약 추가 예시- `@Column`(name = "impressions")
- private Long impressions;
+ `@Column`(name = "impressions", nullable = false)
+ private Long impressions; // 기본값 0 처리는 서비스 레이어에서 담당
- `@Column`(name = "clicks")
- private Long clicks;
+ `@Column`(name = "clicks", nullable = false)
+ private Long clicks;
- `@Column`(name = "conversions")
- private Long conversions;
+ `@Column`(name = "conversions", nullable = false)
+ private Long conversions;🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| @Column(name = "spend", precision = 18, scale = 2) | ||||||||||
| private BigDecimal spend; // 광고비 | ||||||||||
|
|
||||||||||
| @Column(name = "revenue", precision = 18, scale = 2) | ||||||||||
| private BigDecimal revenue; // 매출 | ||||||||||
|
|
||||||||||
| @Enumerated(EnumType.STRING) | ||||||||||
| @Column(name = "provider", nullable = false) | ||||||||||
| private Provider provider; | ||||||||||
|
|
||||||||||
| // 연관 관계 | ||||||||||
| @ManyToOne(fetch = FetchType.LAZY) | ||||||||||
| @JoinColumn(name = "project_id") | ||||||||||
| private Project project; | ||||||||||
|
|
||||||||||
| //추가 연관관계 -> Advertisement | ||||||||||
| @ManyToOne(fetch = FetchType.LAZY) | ||||||||||
| @JoinColumn(name = "ad_id", nullable = false) | ||||||||||
| private Advertisement advertisement; | ||||||||||
| } | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.persistence.repository; | ||
|
|
||
| import com.whereyouad.WhereYouAd.domains.advertisement.persistence.entity.MetricFact; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface MetricFactRepository extends JpaRepository<MetricFact, Long> { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.presentation; | ||
|
|
||
| import com.whereyouad.WhereYouAd.domains.advertisement.presentation.docs.AdvertisementControllerDocs; | ||
| import lombok.AccessLevel; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @RequestMapping("/api/advertisement") | ||
| public class AdvertisementController implements AdvertisementControllerDocs { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.domains.advertisement.presentation.docs; | ||
|
|
||
| public interface AdvertisementControllerDocs { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.application.dto.request; | ||
|
|
||
| public class ProjectRequest { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.application.dto.response; | ||
|
|
||
| public class ProjectResponse { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.application.mapper; | ||
|
|
||
| public class ProjectConverter { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.domain.service; | ||
|
|
||
| public interface ProjectService { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.domain.service; | ||
|
|
||
| import lombok.AccessLevel; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| @Transactional | ||
| @RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class ProjectServiceImpl implements ProjectService{ | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.exception; | ||
|
|
||
| import com.whereyouad.WhereYouAd.global.exception.AppException; | ||
| import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; | ||
|
|
||
| public class ProjectException extends AppException { | ||
| public ProjectException(BaseErrorCode code) { | ||
| super(code); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||||||||||
| package com.whereyouad.WhereYouAd.domains.project.exception.code; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; | ||||||||||||||||||||||||||||||
| import lombok.AllArgsConstructor; | ||||||||||||||||||||||||||||||
| import lombok.Getter; | ||||||||||||||||||||||||||||||
| import org.springframework.http.HttpStatus; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Getter | ||||||||||||||||||||||||||||||
| @AllArgsConstructor | ||||||||||||||||||||||||||||||
| public enum ProjectErrorCode implements BaseErrorCode { | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final HttpStatus httpStatus; | ||||||||||||||||||||||||||||||
| private final String code; | ||||||||||||||||||||||||||||||
| private final String message; | ||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+16
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. ProjectErrorCode에 enum 상수 정의가 필요합니다. Line 10-12처럼 상수가 비어 있으면 ProjectException에서 사용할 오류 코드가 없어 예외 매핑이 불가능합니다. 최소한 대표 오류(예: NOT_FOUND, FORBIDDEN 등)를 정의해 주세요. 🔧 예시 추가안 public enum ProjectErrorCode implements BaseErrorCode {
-
- ;
+ PROJECT_NOT_FOUND(HttpStatus.NOT_FOUND, "PROJECT_404", "프로젝트를 찾을 수 없습니다."),
+ PROJECT_FORBIDDEN(HttpStatus.FORBIDDEN, "PROJECT_403", "프로젝트 접근 권한이 없습니다.");📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,34 @@ | ||||||||||||||
| package com.whereyouad.WhereYouAd.domains.project.persistence.entity; | ||||||||||||||
|
|
||||||||||||||
| import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.Organization; | ||||||||||||||
| import com.whereyouad.WhereYouAd.global.common.BaseEntity; | ||||||||||||||
| import jakarta.persistence.*; | ||||||||||||||
| import lombok.*; | ||||||||||||||
|
|
||||||||||||||
| @Entity | ||||||||||||||
| @Getter | ||||||||||||||
| @Table(name = "project") | ||||||||||||||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||||||||||||||
| @AllArgsConstructor | ||||||||||||||
| @Builder | ||||||||||||||
| public class Project extends BaseEntity { | ||||||||||||||
|
|
||||||||||||||
| @Id | ||||||||||||||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||||||||||
| @Column(name = "project_id") | ||||||||||||||
| private Long id; | ||||||||||||||
|
|
||||||||||||||
| @Column(name = "name", nullable = false) | ||||||||||||||
| private String name; | ||||||||||||||
|
|
||||||||||||||
| @Column(name = "description") | ||||||||||||||
| private String description; | ||||||||||||||
|
|
||||||||||||||
| @Column(name = "created_by", nullable = false) | ||||||||||||||
| private Long createdBy; | ||||||||||||||
|
|
||||||||||||||
| // 연관 관계 | ||||||||||||||
| @ManyToOne(fetch = FetchType.LAZY) | ||||||||||||||
| @JoinColumn(name = "org_id") | ||||||||||||||
| private Organization organization; | ||||||||||||||
|
Comment on lines
+31
to
+33
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.
모든 🛡️ 제약 추가 예시 `@ManyToOne`(fetch = FetchType.LAZY)
-@JoinColumn(name = "org_id")
+@JoinColumn(name = "org_id", nullable = false)
private Organization organization;만약 비즈니스 규칙상 organization 없는 Project가 유효하다면 현재 코드가 맞습니다. 확인 후 필요 없다면 그대로 두세요. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.persistence.repository; | ||
|
|
||
| import com.whereyouad.WhereYouAd.domains.project.persistence.entity.Project; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface ProjectRepository extends JpaRepository<Project, Long> { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.presentation; | ||
|
|
||
| import com.whereyouad.WhereYouAd.domains.project.presentation.docs.ProjectControllerDocs; | ||
| import lombok.AccessLevel; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @RequestMapping("/api/project") | ||
| public class ProjectController implements ProjectControllerDocs { | ||
|
Comment on lines
+8
to
+11
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. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# 프로젝트 내 모든 Java 컨트롤러의 `@RequiredArgsConstructor` 패턴 확인
echo "=== Searching for `@RequiredArgsConstructor` patterns in controllers ==="
rg -n "@RequiredArgsConstructor" --type java -A 2 -B 0
echo -e "\n=== Searching in presentation layer specifically ==="
find . -path "*/presentation/*" -name "*Controller.java" -type f | head -20Repository: WhereYouAd/WhereYouAd-Backend Length of output: 9900
현재는 final 필드가 없어서 문제가 없지만, 나중에 서비스 필드( 코드베이스를 살펴보니 대부분의 컨트롤러(
🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.domains.project.presentation.docs; | ||
|
|
||
| public interface ProjectControllerDocs { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.google.converter; | ||
|
|
||
|
Collaborator
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. P4: infrastructure 에 추후 API 연동 위한 확장 구조 해놓은 거 좋은거 같습니다!! |
||
| public class GoogleConverter { | ||
| // GoogleDTO -> MetricFactResponse 변환 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.google.dto; | ||
|
|
||
| public class GoogleDTO { | ||
| // Google 응답 원문 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.kakao.converter; | ||
|
|
||
| public class KakaoConverter { | ||
| // KakaoDTO -> MetricFactResponse 변환 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.kakao.dto; | ||
|
|
||
| public class KakaoDTO { | ||
| // Kakao 응답 원문 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.naver.converter; | ||
|
|
||
| public class NaverConverter { | ||
| // NaverDTO -> MetricFactResponse 변환 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package com.whereyouad.WhereYouAd.infrastructure.client.naver.dto; | ||
|
|
||
| public class NaverDTO { | ||
| // Naver 응답 원문 | ||
| } |
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.
TODO 주석 누락 및 Java 17
record패턴 미적용AdvertisementResponse에는// TODO: 대시보드 공통 응답값 정의주석이 있는데,AdvertisementRequest에는 없습니다. 나중에 요청 필드를 정의해야 한다는 사실을 잊기 쉬우니 TODO를 추가해주세요.또한 기존 코드베이스의
EmailRequest,SmsRequest처럼 요청 케이스별로 내부record를 사용하는 패턴이 정착되어 있습니다. 필드를 추가할 때 동일한 패턴을 따라주세요.♻️ 개선 예시
public class AdvertisementRequest { + // TODO: 광고 요청 DTO 필드 정의 + + // 예시 — 요청 케이스별 내부 record: + // public record Search(String platform, String campaignName) {} + // public record Create(String campaignName, ...) {} }📝 Committable suggestion
🤖 Prompt for AI Agents