Skip to content

Commit

Permalink
Feat/entity delete (#312)
Browse files Browse the repository at this point in the history
* refactor(Login): 멤버 로그인 로직을 기능별로 모듈화

* refactor(JobPosting): 채용 공고 목록 조회, 채용 공고 검색 API 통합 및 QueryDSL을 통해 처리하도록 변경

* refactor(JobPosting): 채용 공고 등록 로직 개선

* refactor(Donation): 후원 정보, 후원 검색 API 통합 및 QueryDSL을 통해 처리하도록 변경

* refactor(Donation): 후원 생성 로직 간소화 및 수정/삭제 조건 검사 로직 메소드로 분리

* refactor(Comment): 댓글 생성 로직 간소화 및 조건 검사 로직 메소드로 분리

* refactor(Comment): 댓글 생성 로직 간소화

* refactor(Comment): 댓글 좋아요 및 소유자 확인 로직을 도메인으로 이전

* refactor(Comment): 댓글 좋아요 로직 수정

* refactor(Comment): 댓글 좋아요 메소드명 변경

* refactor(Comment): 댓글 생성 로직 모듈화

* refactor(Comment): 댓글 조회 로직 모듈화

* refactor(Book): 도서 목록, 도서 검색 API 통합

* refactor(Book): 도서 조회 공통 로직 메소드로 분리

* refactor(BookLoanRecord): 불필요 예외 제거 및 메소드명 변경

* refactor(Review): 메소드명 변경

* refactor(BookLoanRecord): 도서 대출 로직 일부를 도메인으로 이전

* refactor(Review): 메소드명 변경

* refactor(BookLoanRecord): 도서 반납 로직 일부를 도메인으로 이전

* refactor(BookLoanRecord): 도서 연장 로직 일부를 도메인으로 이전

* refactor(Board): 게시글 좋아요 로직 일부를 도메인으로 이전

* refactor(Board): 주석 제거

* refactor(Board): 게시글 생성 로직 일부를 도메인으로 이전 및 메소드 분리

* refactor(Board): 게시글 상세 조회 로직 일부를 도메인으로 이전 및 메소드 분리

* refactor(Board): 게시글 수정/삭제 권한 로직을 도메인으로 이전

* refactor(Blog): 블로그 포스트 목록 조회, 블로그 포스트 검색 통합 및 QueryDSL을 통해 처리하도록 변경

* refactor(Blog): 일부 서비스 로직을 도메인으로 이전

* refactor(BlacklistIp): 블랙리스트 IP 추가 로직 개선

* refactor(Award): 수상 이력 검색 로직을 QueryDSL을 통해 처리하도록 변경

* refactor(Award): 수상 이력 등록 로직 간소화

* refactor(Award): 수상 이력 수정/삭제 권한 로직을 도메인으로 이전

* refactor(Application): 지원자 목록 조회 repository 코드 분리 및 path명 변경

* refactor(Application): 지원자 합격/취소 로직을 도메인으로 이전

* refactor(Application): 동아리 지원 API 로직 간소화 및 일부 로직 도메인으로 이전

* refactor(Application): 합격 여부 조회 로직 개선

* refactor(ActivityPhoto): 활동 사진 목록 조회, 공개된 활동 사진 목록 조회 API 통합 및 QueryDSL을 통해 처리하도록 변경

* refactor(ActivityPhoto): 활동 사진 등록 로직 개선

* refactor(ActivityPhoto): 활동 사진 고정/해제 로직 도메인으로 이전

* refactor(toggle): 메소드명 변경

* refactor(Accuse): 신고 내역 조회, 유형/상태별 신고 내역 조회 API 통합 및 QueryDSL을 통해 처리하도록 변경

* refactor(Accuse): 신고하기 및 신고 상태 변경 API 로직 개선

* refactor(QueryDSL): JPAQueryFactory을 스프링 빈으로 등록하여 주입받도록 변경

* refactor(WorkExperience): 권한 검사 로직 도메인으로 이전 및 경력사항 생성 오류 수정

* refactor(Schedule): 일정 생성 로직 개선

* refactor(Schedule): 일부 로직 도메인으로 이전

* refactor(Schedule): 일정 조회 로직을 QueryDSL을 통해 처리하도록 변경

* refactor(Schedule): 일정 조회시 LocalDate를 입력받도록 변경

* refactor(Schedule): 일부 로직을 도메인으로 이전

* refactor(Review): 일부 로직을 도메인으로 이전

* refactor(Schedule): 모집 공고 등록 로직 개선

* refactor(Recruitment): 모집 공고 등록 로직 개선

* refactor(Position): 직책 등록 로직 개선

* refactor(Notification): 알림 삭제 권한 로직을 도메인으로 이전

* refactor(News): 메소드명 변경(of -> create)

* refactor(MembershipFee): 회비 수정/삭제 권한 로직을 도메인으로 이전

* refactor(MemberCloud): 클라우드 접근 권한 로직을 도메인으로 이전

* refactor(Member): 일부 로직 도메인으로 이전

* fix(Email): 계정 발급시 비밀번호가 보이지 않는 오류 수정

* refactor(Member): 비밀번호 생성 로직 verificationCodeService로 이동

* refactor(Authenticator): GoogleAuthenticator를 스프링 빈으로 등록하여 주입받도록 변경

* refactor(Authenticator): Authenticator 정적 팩토리 메소드를 이용하여 인스턴스화 로직을 캡슐화

* refactor(LoginAttemptLog): LoginAttemptLog 생성 로직 간소화

* refactor(RedisToken): RedisToken 생성 로직 간소화

* refactor(RedisToken): IP 비교 메소드 도메인으로 이전

* refactor(Comment): 댓글 수정/삭제 권한 로직을 도메인으로 이전

* refactor(ActivityPhoto): 업로드 파일 가져오는 로직 메소드로 분리

* refactor(SharedAccount): 공동계정 생성 로직 간소화

* refactor(SharedAccountUsage): 공동 계정 이용 신청 로직 일부를 도메인으로 이전

* refactor(SharedAccountUsage): 조건 검사 메소드 분리 세분화

* refactor(SharedAccountUsage): 공동 계정 이용 상태 변경 로직 일부를 도메인으로 이전

* refactor(SharedAccountUsage): 기능별 메소드 분리

* refactor(ActivityGroup): 활동 생성 일부 로직을 도메인으로 이동

* refactor(ActivityGroup): 일부 로직을 도메인으로 이동

* refactor(Validation): 컨트롤러에서 예외를 추가로 처리하지 않기로 변경

* refactor(Validation): 유효성 검사 로그 상세화

* refactor(Attendance): static 변수 및 불필요 메소드 제거

* refactor(Attendance): 기능별 메소드 분리

* refactor(ActivityGroupReport): 기능별 메소드 분리

* refactor(ActivityGroupMember): 일부 로직을 도메인으로 이전

* refactor(ActivityGroupMember): 활동 전체 목록 조회 최적화

* refactor(ActivityGroupMember): 활동 상태별 조회 조회 최적화

* refactor(ActivityGroupMember): 활동 상태별 조회 최적화

* refactor(ActivityGroupMember): 일부 로직 도메인으로 이전

* refactor(ActivityGroupBoard): 활동 그룹 게시판 생성 일부 로직 도메인으로 이전 및 메소드 분리

* refactor(ActivityGroupBoard): 활동 그룹 게시판 계층 구조적 조회 일부 로직 도메인으로 이전

* refactor(ActivityGroupBoard): 나의 제출 과제 및 피드백 조회, 활동 그룹 게시판 수정/삭제 로직 최적화 및 도메인 이전

* refactor(ActivityGroupBoard): getChildBoards() 로직 간소화

* refactor(ActivityGroupBoard): validateParentBoard() 로직 최적화

* refactor(ActivityGroupBoard): 신청 멤버 상태 변경 일부 로직 도메인 이전

* refactor(ActivityGroupAdmin): 신청 멤버 상태 변경 일부 로직 도메인 이전

* refactor(VerificationCode): 일부 로직 도메인 이전

* refactor(RedisIpAccessMonitor): 일부 로직 도메인 이전

* refactor(Repository): Custom Repository에서 where 조건을 BooleanBuilder를 통해 표현하도록 수정

* Delete config directory

* refactor(Optimize): 조회 API의 트랜젠션을 readOnly로 변경

* refactor(Validation): 비즈니스 로직에서 중앙집중적으로 유효성을 검사할 수 있도록 함, ExceptionHandler에 ConstraintViolationException 추가

* refactor(Validation): 도메인 지식에 대한 유효성 검사를 비즈니스 로직에서 하도록 변경

* refactor(DB): updateTime -> updatedAt 칼럼명 변경 및 수정일자 갱신 누락 추가

* refactor(Entity): BaseEntity를 통해 생성 및 수정일자를 관리할 수 있도록 함

* refactor(DDD): 도메인 계층으로부터 객체 변환 로직을 분리하여 표현 계층(DTO)으로 이동

* refactor(FileUpload): UploadedFile 로직 분리 및 출석 QR 코드 생성 로직 개선

* refactor(FileUpload): 파일 업로드 메소드 통합

* refactor(FileUpload): 파일 저장 메소드 개선

* refactor(FileUpload): 파일 삭제 로직을 FileHandler로 이동

* refactor(Verification): 패키지명 변경

* refactor(AutoDeleteService): 파일 자동 삭제 로직 가독성 개선

* refactor(EncryptionUtil): EncryptionUtil 빈 주입 개선

* refactor(API): URI Versioning 추가 (/api/{version})

* refactor(MembershipFee): 회비 상태 추가(대기/보류/승인/반려)

* refactor(memberServie): 프로필 사진 빈 문자열로 업데이트 시 기존 파일 삭제와 DB내 null 처리 #299

* refactor(autoDeleteService) : 파일 자동 삭제 시 DB에 등록되지 않은 unknown 파일 삭제 #299

* fix(autoDeleteService): 스케쥴링 cron 설정 원래대로 수정 #299

* refactor(Member): 프로필 사진 업데이트 리팩토링

* refactor(Member): 프로필 사진 업데이트 리팩토링 #299

* refactor(DeleteFileRequestDto): 변수명 복구

* refactor(ActivityGroup): 나의 활동 목록 조회 API 추가

* refactor(BookLoanRecord): 도서 대출 내역 조회시 책 제목, 사진을 함께 반환하도록 변경

* refactor(MembershipFee): 회비 신청시 상태를 입력받지않고 PENDING을 기본값으로 설정

* refactor(Book): 도서에 출판사 후기 URL 칼럼 추가(JSON 저장)

* refactor(MembershipFee): 회비에 계좌 칼럼 추가

* fix(FileUpload): 파일 업로드시 게시글, 회비 등에 대해 구분자가 없어지면서 기존 파일이 삭제되는 문제 수정

* refactor(MembershipFee): 회비 조회시 관리자에게만 계좌 정보가 보이도록 설정

* refactor(MembershipFee): 회비 정보 조회 설명 추가

* refactor(Book): 도서 상세 정보 조회시에만 리뷰 링크를 반환하도록 변경

* fix(Book): 도서 목록 조회 페이지네이션 누락 수정

* fix(Book): 도서 목록 조회 totalPages 미작동 문제 수정

* chore: Create README.md

* chore: Create CONTRIBUTING.md

* Update README.md

* refactor(Board): Dto 필드명 상세화

* refactor(Board): 게시글 목록 조회 반환 정보 추가

* Update README.md

* refactor(WorkExperience): 검색 API 엔드포인트 변경

* refactor(DTO): 불필요한 Lombok 어노테이션 제거

* refactor(EqualsAndHashCode): 일부 Entity에서 저장할 때 데이터가 중복되던 문제 수정

* refactor(Constructor): Entity 생성자에 대한 접근 제한 설정

* refactor(Util): 불필요한 어노테이션 제거

* refactor(CompositeKey): 복합키 캡슐화

* refactor(DTO): ResponseDto 불변성을 위한 Setter 제거

* refactor(ResponseModel): ResponseModel DDD에 맞게 재설계 및 그에 따른 관련 로직 수정

* refactor(RedisIpAccessMonitor): 비정상 접근 IP 기록 초기화시 초기화된 IP 리스트를 반환하도록 변경

* refactor(Email): 이메일 전송시 전송 완료된 이메일 주소를 반환하도록 변경

* refactor(BlacklistIp): 블랙리스트 IP 초기화시 초기화된 IP 리스트를 반환하도록 변경

* refactor(Member): 멤버 비밀번호 재발급/요청시 멤버 ID를 반환하도록 변경

* refactor(Member): 내 프로필 조회시 재학 상태를 반환하도록 변경

* refactor(Enum): 운영진 Enum값 수정

* refactor(Board): 게시글 카테고리 Enum으로 고정

* refactor(BlacklistIp): 슬랙 메시지 오타 수정

* refactor(BlacklistIp): 의심스러운 활동으로 인한 차단시 블랙리스트 추가 사유를 기록하도록 수정

* fix(GeoIp): GeoIp DB를 불러오지 못할 경우 Unknown을 반환하도록 수정

* refactor(Board): BoardCategory GRADUATE -> GRADUATED 변경

* refactor(Board): BoardCategory 정보를 소문자로 반환하도록 변경

* refactor(Job,News): 채용 공고, IT 뉴스 반환 정보에 생성일자 추가

* feat(Login): 현재 로그인 중인 멤버 조회 API 추가

* refactor(Accuse): 확장성을 고려한 신고 시스템 재설계

* refactor(Accuse): 신고하기 로직 리팩토링

* refactor(Accuse): 신고 테이블 구조 및 신고 내역 조회 응답 변경, 누적 횟수 기준으로 정렬할 수 있도록 함.

* refactor(Accuse): 신고 시스템 재설계에 따른 신고 상태 변경 API 수정 및 리팩토링

* refactor(Board): 게시글 상세 조회시 익명 유저일 경우 권한 정보를 반환하지 않도록 변경

* refactor(Board): 게시글 상세 조회 및 댓글 조회시 작성자의 ID, 이름을 모두 반환하도록 변경

* feat(Schedule): 일정 중요도 및 조건별 검색 API 추가

* feat(Schedule): 일정 모아보기 API 추가

* feat(Board): 게시판 카테고리에 동아리 소식 추가

* ci: add spring boot gradle ci (#304)

* docs: add gradle ci badge (#304)

* ci: update spring-boot-gradle-ci (#304)

* refactor(Actuator): 헬스 체크를 위한 권한 설정 변경

* refactor(test): Test 환경 설정

* refactor(Schedule): 일정 조회시 기간 내 진행중인 일정 모든 일정에 대해 조회하도록 변경

* refactor(Book): 도서 대출 내역 조회시 대출자의 이름을 같이 반환하도록 수정

* fix(Member): 멤버 정보 수정시 Optional로 인해 발생하는 오류 수정

* feat(Book): 도서 연체자 조회 API 추가

* fix: 이메일 전송 시 html 파일 경로 지정용 ThymeleafConfig 추가 #299

* chore: 배포 환경 설정

* chore: 배포 환경 변경(prod->stage)

* chore: gradle build시 프로필을 유동적으로 사용할 수 있도록 변경

* refactor(Board): 커뮤니티 게시글 카테고리별 조회시 writerId를 반환하도록 변경

* refactor(Board): 커뮤니티 게시글 카테고리별 조회 엔드포인트 변경

* refactor(Board): 썸네일 이미지 URL 컬럼 추가

* fix(Board): 썸네일 이미지 URL 업데이트 로직 누락 수정

* refactor(File): 게시글 사진 업로드 -> 게시글 파일 업로드 Operation 수정

* refactor(Accuse): 자신의 콘텐츠에 대해 신고할 수 없도록 변경

* feat(Accuse): 나의 신고 내역 조회 API 추가

* feat(Book): 도서 대여 승인 제도 추가

* refactor(Book): 도서 대여 승인 제도 추가에 따른 도서 연체자 조회 로직 수정

* refactor(Book): 도서 대출 내역 조회시 대출 여부 대신 대출 상태를 기준으로 조회 가능하도록 변경

* refactor: 유효성 검사 및 트랙젝션 누락 수정

* feat(Book): 최대 도서 대여 개수 정책 추가

* refactor(Book): 도서 대출 내역, 연체자 조회시 대출 상태를 같이 반환하도록 변경

* refactor(Exception): 미사용 예외 삭제

* refactor(Exception): 예외 재분류

* refactor(Book): 도서 대출 내역 조회시 borrowedAt이 없는 경우를 고려하여 createdAt을 두 번째 정렬 기준으로 추가

* refactor(Exception): 409 예외 처리 및 응답 변경

* fix(Book): 중복 도서 대출 요청 수정

* refactor(Book): 대출 중인 도서도 대출 요청 가능하도록 변경

* feat: Board soft delete 구현 #299

* refactor(Exception): ErrorResponse 분리

* refactor(Response): ResponseModel -> ApiResponse 이름 변경

* chore: Dockerfile 수정

* chore: Dockerfile 수정(JDK 21 강제화)

* chore: Dockerfile 롤백

* fix: Board 관련 소프트 딜리트, 조회 로직 수정, 삭제한 Board 조회 api 작성 #299

* fix: board 소프트 딜리트 @where과 nativeQuery를 사용해 구현 #299

* fix: award 소프트 딜리트 구현, where 어노테이션 deprecated 이슈로 SQLRestriction 사용 #299

* fix: Blog 소프트 딜리트 구현 #299

* fix: Book 소프트 딜리트 구현 #299

* fix: Donation 소프트 딜리트 구현 #299

* fix : JobPosting 소프트 딜리트 구현 #299

* fix: MembershipFee 소프트 딜리트 구현 #299

* fix: News 소프트 딜리트 구현 #299

* fix: Notification 소프트 딜리트 구현 #299

* fix: Position 소프트 딜리트 구현 #299

* fix: Product 소프트 딜리트 #299

* fix: Recruitment 소프트 딜리트 구현 #299

* fix: Review 소프트 딜리트 구현 #299

* fix: Schedule 소프트 딜리트 #299

* fix: SharedAccount 소프트 딜리트 구현 #299

* fix: WorkExperience 소프트 딜리트 구현 #299

* fix: Application 소프트 딜리트 방식 수정 및 Book 하드 딜리트 전환. 버그 발견 #299

* feat: Comment 자체 소프트 딜리트 구현과 삭제된 댓글입니다를 구현할 수 있도록 응답 로직 수정 #299

* feat(IPInfo): IPInfo 라이브러리에 누락된 Context 관련 파일 작성

* refactor(IpAuthenticationFilter): 해외 접속시 국가 코드가 아닌 국가명이 출력되도록 변경

* fix: ActivityGroup 소프트 딜리트 작성 #299

* fix: ActivityGroupBoard 소프트 딜리트 작성 #299

* fix: ActivityGroupReport 소프트 딜리트 작성 #299

* fix: Book 커스텀 소프트 딜리트 재작성 #299

* feat(Slack): 보안 경고 알림에 클라이언트의 위치 정보 추가

* refactor(LoginAttemptLog): 로그인 기록에 국가 정보 추가

* refactor(IpAuthenticationFilter): 로깅 강화

* refactor: 삭제된 데이터 조회에 대한 transactional read only 설정

* refactor: GeoIP2 제거

---------

Co-authored-by: mingmingmon <[email protected]>
Co-authored-by: 김관식 <[email protected]>
  • Loading branch information
3 people authored Apr 28, 2024
1 parent e4d6d53 commit 3c53b61
Show file tree
Hide file tree
Showing 97 changed files with 1,800 additions and 110 deletions.
148 changes: 74 additions & 74 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,111 +1,111 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.1'
id 'io.spring.dependency-management' version '1.1.4'
id 'java'
id 'org.springframework.boot' version '3.2.1'
id 'io.spring.dependency-management' version '1.1.4'
}

group = 'page.clab'
version = '0.0.1-SNAPSHOT'

jar {
enabled = false
enabled = false
}

bootJar {
archivesBaseName = "clab"
archiveFileName = "clab.jar"
archiveVersion = "1.0.0"

if (project.hasProperty('prod')) {
archiveFileName = "clab-prod.jar"
} else if (project.hasProperty('stage')) {
archiveFileName = "clab-stage.jar"
} else {
archiveFileName = "clab.jar"
}
archivesBaseName = "clab"
archiveFileName = "clab.jar"
archiveVersion = "1.0.0"

if (project.hasProperty('prod')) {
archiveFileName = "clab-prod.jar"
} else if (project.hasProperty('stage')) {
archiveFileName = "clab-stage.jar"
} else {
archiveFileName = "clab.jar"
}
}

test {
systemProperty 'spring.profiles.active', findProperty('env') ?: 'dev'
systemProperty 'spring.profiles.active', findProperty('env') ?: 'dev'
}

java {
sourceCompatibility = '21'
sourceCompatibility = '21'
}

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
mavenCentral()
maven { url 'https://jitpack.io' }
}

dependencies {
// Spring Project
implementation 'org.springframework.boot:spring-boot-starter-actuator' // 모니터링
implementation 'org.springframework.boot:spring-boot-starter-web' // 웹 MVC
implementation 'org.springframework.boot:spring-boot-starter-validation' // 유효성 검사
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // 템플릿 엔진
implementation 'org.springframework.boot:spring-boot-starter-webflux' // WebFlux
developmentOnly 'org.springframework.boot:spring-boot-devtools' // 개발 도구

// Util
compileOnly 'org.projectlombok:lombok' // 롬복
annotationProcessor 'org.projectlombok:lombok' // 롬복
implementation 'com.google.code.gson:gson:2.10.1' // JSON 라이브러리
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' // Swagger
implementation 'commons-io:commons-io:2.15.1' // Apache Commons IO
implementation 'com.google.guava:guava:33.0.0-jre' // Google Core Libraries For Java
implementation 'org.springframework.boot:spring-boot-starter-mail' // Spring Mail
implementation 'com.google.zxing:core:3.4.1' // QR 코드
implementation 'com.google.zxing:javase:3.4.1' // QR 코드
implementation 'com.slack.api:slack-api-client:1.38.0' // Slack API
implementation 'io.ipinfo:ipinfo-spring:0.3.1' // IPInfo


// DB
implementation 'org.postgresql:postgresql:42.7.1' // PostgreSQL JDBC Driver
implementation 'org.springframework.boot:spring-boot-starter-data-redis' // Redis
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // Spring Data JPA
implementation 'org.springframework.boot:spring-boot-starter-validation' // Hibernate Validator
implementation 'org.hibernate.validator:hibernate-validator:8.0.1.Final' // Bean Validation
implementation 'jakarta.validation:jakarta.validation-api:3.0.2' // Jakarta Bean Validation

// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.1.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// Security
implementation 'org.springframework.boot:spring-boot-starter-security' // Spring Security
implementation 'com.warrenstrange:googleauth:1.5.0' // Google Authenticator
implementation 'io.jsonwebtoken:jjwt-api:0.11.5' // JWT 라이브러리
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' // JWT 구현체
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // JWT Jackson 모듈

// XSS Filter
implementation 'com.navercorp.lucy:lucy-xss-servlet:2.0.1' // Lucy XSS Servlet Filter
implementation 'com.navercorp.lucy:lucy-xss:1.6.3' // Lucy XSS Filter
implementation 'org.apache.commons:commons-text:1.11.0' // Apache Commons Text

// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test' // Spring Boot Test
testImplementation 'org.springframework.security:spring-security-test' // Spring Security Test
// Spring Project
implementation 'org.springframework.boot:spring-boot-starter-actuator' // 모니터링
implementation 'org.springframework.boot:spring-boot-starter-web' // 웹 MVC
implementation 'org.springframework.boot:spring-boot-starter-validation' // 유효성 검사
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // 템플릿 엔진
implementation 'org.springframework.boot:spring-boot-starter-webflux' // WebFlux
developmentOnly 'org.springframework.boot:spring-boot-devtools' // 개발 도구

// Util
compileOnly 'org.projectlombok:lombok' // 롬복
annotationProcessor 'org.projectlombok:lombok' // 롬복
implementation 'com.google.code.gson:gson:2.10.1' // JSON 라이브러리
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' // Swagger
implementation 'commons-io:commons-io:2.15.1' // Apache Commons IO
implementation 'com.google.guava:guava:33.0.0-jre' // Google Core Libraries For Java
implementation 'org.springframework.boot:spring-boot-starter-mail' // Spring Mail
implementation 'com.google.zxing:core:3.4.1' // QR 코드
implementation 'com.google.zxing:javase:3.4.1' // QR 코드
implementation 'com.slack.api:slack-api-client:1.38.0' // Slack API
implementation 'io.ipinfo:ipinfo-spring:0.3.1' // IPInfo


// DB
implementation 'org.postgresql:postgresql:42.7.1' // PostgreSQL JDBC Driver
implementation 'org.springframework.boot:spring-boot-starter-data-redis' // Redis
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // Spring Data JPA
implementation 'org.springframework.boot:spring-boot-starter-validation' // Hibernate Validator
implementation 'org.hibernate.validator:hibernate-validator:8.0.1.Final' // Bean Validation
implementation 'jakarta.validation:jakarta.validation-api:3.0.2' // Jakarta Bean Validation

// QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.1.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// Security
implementation 'org.springframework.boot:spring-boot-starter-security' // Spring Security
implementation 'com.warrenstrange:googleauth:1.5.0' // Google Authenticator
implementation 'io.jsonwebtoken:jjwt-api:0.11.5' // JWT 라이브러리
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' // JWT 구현체
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // JWT Jackson 모듈

// XSS Filter
implementation 'com.navercorp.lucy:lucy-xss-servlet:2.0.1' // Lucy XSS Servlet Filter
implementation 'com.navercorp.lucy:lucy-xss:1.6.3' // Lucy XSS Filter
implementation 'org.apache.commons:commons-text:1.11.0' // Apache Commons Text

// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test' // Spring Boot Test
testImplementation 'org.springframework.security:spring-security-test' // Spring Security Test
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}

def querydslDir = "$buildDir/generated/querydsl"

sourceSets {
main.java.srcDirs += [ querydslDir ]
main.java.srcDirs += [ querydslDir ]
}

tasks.withType(JavaCompile) {
options.generatedSourceOutputDirectory = file(querydslDir)
options.generatedSourceOutputDirectory = file(querydslDir)
}

clean.doLast {
file(querydslDir).deleteDir()
file(querydslDir).deleteDir()
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupRequestDto;
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupUpdateRequestDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupMemberWithApplyReasonResponseDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupResponseDto;
import page.clab.api.domain.award.dto.response.AwardResponseDto;
import page.clab.api.global.common.dto.PagedResponseDto;
import page.clab.api.global.common.dto.ApiResponse;
import page.clab.api.global.exception.PermissionDeniedException;
Expand Down Expand Up @@ -130,4 +132,16 @@ public ApiResponse<String> acceptGroupMember(
return ApiResponse.success(id);
}

@GetMapping("/deleted")
@Operation(summary = "[S] 삭제된 활동그룹 조회하기", description = "ROLE_SUPER 이상의 권한이 필요함")
@Secured({"ROLE_SUPER"})
public ApiResponse<PagedResponseDto<ActivityGroupResponseDto>> getDeletedActivityGroups(
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "20") int size
) {
Pageable pageable = PageRequest.of(page, size);
PagedResponseDto<ActivityGroupResponseDto> activityGroups = activityGroupAdminService.getDeletedActivityGroups(pageable);
return ApiResponse.success(activityGroups);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupBoardResponseDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupBoardUpdateResponseDto;
import page.clab.api.domain.activityGroup.dto.response.AssignmentSubmissionWithFeedbackResponseDto;
import page.clab.api.domain.award.dto.response.AwardResponseDto;
import page.clab.api.global.common.dto.PagedResponseDto;
import page.clab.api.global.common.dto.ApiResponse;
import page.clab.api.global.exception.PermissionDeniedException;
Expand Down Expand Up @@ -137,4 +138,16 @@ public ApiResponse<Long> deleteActivityGroupBoard(
return ApiResponse.success(id);
}

@GetMapping("/deleted")
@Operation(summary = "[S] 삭제된 활동 그룹 게시판 조회하기", description = "ROLE_SUPER 이상의 권한이 필요함")
@Secured({"ROLE_SUPER"})
public ApiResponse<PagedResponseDto<ActivityGroupBoardResponseDto>> getDeletedActivityGroupBoards(
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "20") int size
) {
Pageable pageable = PageRequest.of(page, size);
PagedResponseDto<ActivityGroupBoardResponseDto> activityBoards = activityGroupBoardService.getDeletedActivityGroupBoards(pageable);
return ApiResponse.success(activityBoards);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupReportRequestDto;
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupReportUpdateRequestDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupReportResponseDto;
import page.clab.api.global.common.dto.PagedResponseDto;
import page.clab.api.global.common.dto.ApiResponse;
import page.clab.api.global.common.dto.PagedResponseDto;
import page.clab.api.global.exception.PermissionDeniedException;

@RestController
Expand Down Expand Up @@ -90,4 +90,17 @@ public ApiResponse<Long> deleteAward(
return ApiResponse.success(id);
}


@GetMapping("/deleted")
@Operation(summary = "[S] 삭제된 활동보고서 조회하기", description = "ROLE_SUPER 이상의 권한이 필요함")
@Secured({"ROLE_SUPER"})
public ApiResponse<PagedResponseDto<ActivityGroupReportResponseDto>> getDeletedActivityGroupReports(
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "20") int size
) {
Pageable pageable = PageRequest.of(page, size);
PagedResponseDto<ActivityGroupReportResponseDto> activityGroupReports = activityGroupReportService.getDeletedActivityGroupReports(pageable);
return ApiResponse.success(activityGroupReports);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupRequestDto;
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupUpdateRequestDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupMemberWithApplyReasonResponseDto;
import page.clab.api.domain.activityGroup.dto.response.ActivityGroupResponseDto;
import page.clab.api.domain.member.application.MemberService;
import page.clab.api.domain.member.domain.Member;
import page.clab.api.domain.notification.application.NotificationService;
Expand Down Expand Up @@ -91,11 +92,17 @@ public Long manageActivityGroup(Long activityGroupId, ActivityGroupStatus status
return activityGroup.getId();
}

@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupResponseDto> getDeletedActivityGroups(Pageable pageable) {
Page<ActivityGroup> activityGroups = activityGroupRepository.findAllByIsDeletedTrue(pageable);
return new PagedResponseDto<>(activityGroups.map(ActivityGroupResponseDto::toDto));
}

@Transactional
public Long deleteActivityGroup(Long activityGroupId) {
ActivityGroup activityGroup = getActivityGroupByIdOrThrow(activityGroupId);
List<GroupMember> groupMembers = activityGroupMemberService.getGroupMemberByActivityGroupId(activityGroupId);
List<GroupSchedule> groupSchedules = groupScheduleRepository.findAllByActivityGroupIdOrderByIdDesc(activityGroupId);
ActivityGroup activityGroup = getActivityGroupByIdOrThrow(activityGroupId);
GroupMember groupLeader = activityGroupMemberService.getGroupMemberByActivityGroupIdAndRole(activityGroupId, ActivityGroupRole.LEADER);

activityGroupMemberService.deleteAll(groupMembers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import page.clab.api.domain.activityGroup.dto.response.AssignmentSubmissionWithFeedbackResponseDto;
import page.clab.api.domain.activityGroup.dto.response.FeedbackResponseDto;
import page.clab.api.domain.activityGroup.exception.InvalidParentBoardException;
import page.clab.api.domain.award.domain.Award;
import page.clab.api.domain.award.dto.response.AwardResponseDto;
import page.clab.api.domain.member.application.MemberService;
import page.clab.api.domain.member.domain.Member;
import page.clab.api.domain.notification.application.NotificationService;
Expand Down Expand Up @@ -145,6 +147,12 @@ public Long deleteActivityGroupBoard(Long activityGroupBoardId) throws Permissio
return board.getId();
}

@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupBoardResponseDto> getDeletedActivityGroupBoards(Pageable pageable) {
Page<ActivityGroupBoard> activityGroupBoards = activityGroupBoardRepository.findAllByIsDeletedTrue(pageable);
return new PagedResponseDto<>(activityGroupBoards.map(ActivityGroupBoardResponseDto::toDto));
}

private ActivityGroupBoard getActivityGroupBoardByIdOrThrow(Long activityGroupBoardId) {
return activityGroupBoardRepository.findById(activityGroupBoardId)
.orElseThrow(() -> new NotFoundException("해당 게시글을 찾을 수 없습니다."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public Long deleteReport(Long reportId) throws PermissionDeniedException {
return report.getId();
}

@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupReportResponseDto> getDeletedActivityGroupReports(Pageable pageable) {
Page<ActivityGroupReport> activityGroupReports = activityGroupReportRepository.findAllByIsDeletedTrue(pageable);
return new PagedResponseDto<>(activityGroupReports.map(ActivityGroupReportResponseDto::toDto));
}

public ActivityGroupReport getReportByIdOrThrow(Long reportId) {
return activityGroupReportRepository.findById(reportId)
.orElseThrow(() -> new NotFoundException("활동 보고서를 찾을 수 없습니다."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
import page.clab.api.domain.activityGroup.domain.ActivityGroupBoard;
Expand All @@ -21,4 +22,7 @@ public interface ActivityGroupBoardRepository extends JpaRepository<ActivityGrou

List<ActivityGroupBoard> findAllChildrenByParentId(Long activityGroupBoardId);

@Query(value = "SELECT a.* FROM activity_group_board a WHERE a.is_deleted = true", nativeQuery = true)
Page<ActivityGroupBoard> findAllByIsDeletedTrue(Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import page.clab.api.domain.activityGroup.domain.ActivityGroup;
import page.clab.api.domain.activityGroup.domain.ActivityGroupReport;
Expand All @@ -16,4 +17,7 @@ public interface ActivityGroupReportRepository extends JpaRepository<ActivityGro

boolean existsByActivityGroupAndTurn(ActivityGroup activityGroup, Long turn);

@Query(value = "SELECT a.* FROM activity_group_report a WHERE a.is_deleted = true", nativeQuery = true)
Page<ActivityGroupReport> findAllByIsDeletedTrue(Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;
import page.clab.api.domain.activityGroup.domain.ActivityGroup;
Expand All @@ -15,4 +16,7 @@ public interface ActivityGroupRepository extends JpaRepository<ActivityGroup, Lo

Page<ActivityGroup> findAllByCategoryOrderByCreatedAtDesc(ActivityGroupCategory category, Pageable pageable);

@Query(value = "SELECT a.* FROM activity_group a WHERE a.is_deleted = true", nativeQuery = true)
Page<ActivityGroup> findAllByIsDeletedTrue(Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.URL;
import page.clab.api.domain.activityGroup.dto.request.ActivityGroupUpdateRequestDto;
Expand All @@ -29,6 +31,8 @@
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@SQLDelete(sql = "UPDATE activity_group SET is_deleted = true WHERE id = ?")
@SQLRestriction("is_deleted = false")
public class ActivityGroup extends BaseEntity {

@Id
Expand Down
Loading

0 comments on commit 3c53b61

Please sign in to comment.