Commit dea6e4b
[release] 26-07-21 production 배포 (#603)
* feat: JWT 인증 필터에서 검증 토큰 처리 로직 개선 및 쿠키 삭제 기능 추가
* feat: JWT 인증 필터에서 검증 토큰 쿠키에 보안 속성 추가
* feat: JWT 인증 필터에서 검증 토큰 처리 로직 개선
* feat: JWT 인증 필터에서 검증 토큰 처리 로직 간소화
* feat: JWT 인증 필터에서 액세스 토큰 및 검증 토큰 처리 로직 개선
* feat: 관리자 로그인 및 서포터 토큰 발급 이벤트를 발행하도록 알림 시스템을 이벤트 기반으로 리팩토링 (#405)
* feat: 미니 스터디 설명 필드 추가 (#408)
* feat: MiniStudy 엔티티에 tag 필드 추가
* feat: MiniStudyResponse에 tag 필드 추가
* feat: MiniStudyQueryRepository에 tag 필드 추가
* test: MiniStudyQueryRepositoryTest에 tag 필드 관련 테스트 추가
* feat: mini_study 테이블에 tag 컬럼 추가
* feat: 관리자 지원서 조회 API에 기수 파라미터 추가 (#409)
* feat: 임시 지원서 목록 조회 API에 semesterId 필터 추가
* feat: 제출된 지원서 조회 API에 semesterId 필터 추가
* feat: 제출된 지원서 조회 API에 semesterId 파라미터 추가
* feat: 임시 지원서 조회 API에 semesterId 파라미터 추가
* feat: 지원서 조회 쿼리에 semesterId 파라미터 추가 및 필터링 로직 구현
* test: 지원서 조회 테스트에 semesterId 필터링 테스트 추가
* feat: Jectalk 엔티티 스펙 변경 (#412)
* feat: ContentType enum 추가하여 콘텐츠 유형 정의
* feat: Jectalk 엔티티 및 DTO 구조 변경
* feat: JectalkQueryRepository 반환 필드 수정
* test: JectalkQueryRepositoryTest 수정으로 반환 필드 검증 업데이트
* feat: Jectalk 테이블 구조 변경 및 데이터 마이그레이션으로 인한 Flyway migration 추
* feat: Jectalk 테이블 content_type 컬럼 기본값 추가
* feat: Category 필드 및 필터링 추가
* feat: n8n에 지원서 제출 이벤트 발행 기능 추가 (#415)
* feat: 제출된 지원서 응답에 지역, 경력 사항, 경험 기간 및 관심 분야 추가
* feat: 지원서 응답에 관심 분야가 null일 경우 빈 리스트로 처리하도록 수정
* feat: 질문에 subtitle 컬럼 추가 및 초기화 쿼리 작성 (#421)
* refactor: deprecated 처리된 temporary apply 관련 코드 삭제 (#429)
* refactor: deprecated 처리된 temporary apply 관련 코드 삭제
* refactor: deprecated 처리된 temporary apply 관련 코드 삭제
* refactor: 사용하지 않는 review 코드 삭제 (#428)
* chore: 마이그레이션 스크립트로 review 스키마 제거
* refactor: review 도메인 및 관련 코드 삭제
* refactor: n8n 관련 코드 및 이벤트 발행 로직 제거 (#433)
* refactor: Redis 캐시 설정 및 연결 구성 수정 (#434)
* feat: Redis 캐시 설정 및 연결 구성 추가
* refactor: 레디스 설정 파일 분리 파일 삭제
* feat: 인증번호 재설정 이메일 발송 시 전송 횟수 제한 기능 추가 (#430)
* feat: 인증번호 재설정 이메일 발송 시 rate limiter 로직 추가
* test: 인증번호 재설정 이메일 발송 시 rate limiter 로직 테스트 케이스 추가
* refactor: EmailAuthService import문 정리
* chore: Dockerfile 베이스 이미지 JRE로 변경 및 메모리 설정 최적화 (#432)
* fix: CI/Testcontainers 안정화 (#438)
* test: main 메소드에 CI/CD 테스트 주석 추가
* chore: Dockerfile 빌드 설정 업데이트
* ci: Docker 환경 체크 스텝 추가 및 커버리지 임계값 조정
* fix: 빌드 테스트
* fix: 빌드 테스트, 로그 추가
* fix: docker api version up 1.44
* fix: Redis Testcontainers 이미지를 안정 버전(7.4-alpine)으로 변경
* fix: docker api fix 1.44
* fix: Diagnose Testcontainers Runtime 스텝 추가, Test with Gradle에 아래 강제 옵션 추가
* fix: CI 러너를 고정
* fix: Set up Docker Engine
* fix: docker.api.version=1.44 강제
* fix: Testcontainers CI 연동 수정 및 JaCoCo 임계값 조정
* fix: CI 테스트
* fix: 1.43 다운그레이드
* fix: TestContainers 의존성 관리 및 Redis TestContainer 시작 로직을 안정화했습니다.
* fix: Redis 시작 로그 추가 및 Gradle test 환경변수 설정
* fix: Redis WaitStrategy 변경(포트->로그) 및 타임아웃 120초로 증가
* fix: Redis WaitStrategy 롤백 및 타임아웃 180초로 연장
* chore: 테스트 로그 레벨 조정 (Testcontainers, Docker 관련 로그 WARN으로 변경)
* fix: CI 로그 옵션 제거 및 Testcontainers 설정 수정 (Ryuk 비활성화)
* CI Gradle 테스트에서 Testcontainers를 위한 Docker API 버전과 소켓 전략을 구성하고 디버그 정보를 추가했습니다.
* build: Redis 테스트 컨테이너 이미지를 7.4-alpine에서 8.0-M03-alpine으로 업데이트합니다.
* fix: CI 설정 파일 정리 (dev 브랜치 기준으로 불필요한 설정 제거)
* refactor: Testcontainers 설정 리팩토링 (어노테이션 제거, Redis 7.4 변경, 중복 start 제거)
* style: Unused import 및 어노테이션 정리
* style: MysqlTestContainersConfig Unused import 정리
* style: RedisTestContainersConfig 잔여 Unused import 정리
* feat: MySQL 및 Redis 테스트 컨테이너에 `@Testcontainers` 어노테이션과 `DisposableBean`을 구현하여 컨테이너 생명주기를 관리하도록 개선했습니다.
* fix: CI Docker 환경 인식 오류 수정 (DOCKER_HOST 명시)
* fix: ubuntu-22.04 고정, DOCKER_HOST 고정 테스트
* fix: ubuntu-22.04 고정, DOCKER_HOST 고정 테스트
* fix: 디버깅용 로그 제거, 테스트 로그 레벨 축소 info -> stacktrace
---------
Co-authored-by: fad <ojy9406@naver.com>
* feat: 다직군/다기수 지원을 위한 TeamMember 기반 리팩토링 (#439)
* chore: CI 테스트 커버리지 최소 기준 복구
min-coverage-overall 및 min-coverage-changed-files 설정을 10에서 70으로 변경
* chore: SupportApplication 테스트 주석 제거
- CI/CD 파이프라인 동작 확인용 주석 삭제
* feat: TeamMember에 jobFamily 필드 추가
- TeamMember 엔티티에 jobFamily 필드 추가 (@Enumerated, @column)
- 클래스 레벨에 @Getter 어노테이션 추가
* feat: team_member job_family 데이터 마이그레이션
- 기존 member.job_family 데이터를 team_member.job_family로 마이그레이션하는 SQL 스크립트 추가
* fix: 팀원 조회 시 TeamMember jobFamily 우선 적용 및 Fallback 로직 추가
- MemberQueryRepositoryImpl: 팀원 이름 조회 쿼리 수정
- TeamMember의 jobFamily가 존재하면 해당 값을 우선 사용하도록 변경
- null인 경우 Member의 jobFamily를 사용 (기존 데이터 호환성 유지)
- MemberQueryRepositoryTest: 기수별 다른 직군 활동 및 Fallback 로직 검증 테스트 추가
* fix: 회원 정보 수정 시 TeamMember 직군(jobFamily) 동기화
- MemberManagementService: 회원 정보 수정 시 변경된 직군을 해당 회원의 모든 TeamMember 데이터에 동기화하는 로직 추가
- TeamMember: 직군 변경을 위한 updateJobFamily 메서드 추가
- TeamMemberRepository: findByMemberId 메서드 추가
- MemberManagementServiceTest: 직군 동기화 검증 테스트 추가
* chore: JaCoCo 라인 커버리지 최소 기준 상향 (0.1 → 0.7)
- build.gradle: 테스트 커버리지(LINE) 최소 만족 비율을 10%에서 70%로 변경
* fix: MemberQueryRepositoryTest PM 조회 검증 값 수정
- 2기 팀 PM 조회 결과 검증 시 기대값을 "ject"에서 "김젝트"로 변경
* fix: MemberQueryRepositoryTest 테스트 검증 값 수정
* refactor: 사용되지 않는 DynamoDB 컴포넌트 제거 및 정리 (#444)
* feat: AI 어시스턴트 GitHub 템플릿(Issue/PR) 설계 적용 (#450) (#451)
* feat: apply github templates to ai assistant workflows and skills (#450)
* fix: resolve CodeRabbit review comments on AI templates (#450)
* fix: resolve second-round CodeRabbit review comments on manage-skills and PR workflows (#450)
* fix: resolve third-round CodeRabbit review comments on manage-skills (#450)
* fix: resolve fourth-round CodeRabbit review comments on manage-skills (#450)
* fix: resolve fifth-round CodeRabbit review comments (#450)
* feat: 지원상태 확인 API 수정 (#447)
* [FUNC_APL_MGT_01] 제출 완료된 지원서 목록 조회하기 #449 (#452)
* refactor: admin 패키지로 ApplyQueryRepository 이관
- ApplyQueryRepository, ApplyQueryRepositoryImpl를 admin/repository 패키지로 이관
- AdminApplyQueryRepository, AdminApplyQueryRepositoryImpl로 이름 변경
- ApplyRepository에서 ApplyQueryRepository extends 제거
- SubmittedApplyService, AdminTempApplyService가 AdminApplyQueryRepository를 직접 주입받도록 변경
- ApplyQueryRepositoryTest를 AdminApplyQueryRepositoryTest로 이관
* feat: 제출 완료된 지원서 목록 조회 기능 구현 (#449)
- AdminApplyQueryRepositoryTest에 AdminApplyQueryRepositoryImpl @import 추가
- JobFamily, semesterId 필터링 및 createdAt 내림차순 정렬 지원
- 삭제된 회원의 지원서 제외 처리
- 페이지네이션 지원 (기본 size=15)
* refactor: admin 패키지를 domain 레이어와 동일 레벨로 이관
- org.ject.support.domain.admin → org.ject.support.admin 으로 패키지 이동
- component, controller, dto, exception, repository, service 전체 이관
- 테스트 파일도 동일하게 이관
- 외부에서 참조하는 import도 일괄 수정
- 추후 admin 모듈 분리를 용이하게 하기 위한 패키지 구조 개선
* fix: 제출 지원서 목록 조회 페이지 크기 10, 등록일 내림차순 정렬 기본값 적용
- @PageableDefault size=15 → 10 (이슈 #449 요구사항: 한 페이지 10개)
- sort="createdAt", direction=DESC 기본 정렬 추가
* feat: Recruit에 모집 단위(RecruitType) 추가 및 지원서 목록 조회 필터 반영
- RecruitType enum 추가 (REGULAR, REGULAR_ADDITIONAL, EXISTING_MEMBER, SEPARATE)
- Recruit 엔티티에 recruitType 필드 추가 (nullable)
- V20 Flyway 마이그레이션: recruit 테이블에 recruit_type 컬럼 추가
- AdminApplyQueryRepository.findAppliesByStatus()에 recruitType 필터 파라미터 추가
- SubmittedApplyService, AdminTempApplyService 및 컨트롤러·ApiSpec 전파
- 관련 테스트 파일 호출부 일괄 수정
* fix: RecruitType enum 값 명칭 변경 및 기존 데이터 REGULAR 초기화
- REGULAR_ADDITIONAL → REGULAR_WAITLIST
- EXISTING_MEMBER → BACKFILL
- SEPARATE → MANUAL
- Recruit.recruitType 빌더 기본값 REGULAR 설정, nullable=false
- V20 마이그레이션: 기존 레코드 REGULAR 초기화 후 NOT NULL 적용
* refactor: admin 패키지를 apply/member/auth 기능별 하위 구조로 분리
- admin/apply: 지원서 관리 (controller, dto, repository, service)
- admin/member: 회원 관리 (component, controller, dto, service)
- admin/auth: 인증 (controller, dto, service)
- admin/exception: 공통 예외 (기존 유지)
- 패키지 선언 및 import 일괄 수정
* refactor: SubmittedApplyApiSpec 제거 및 SubmittedApplyController로 통합
* refactor: MemberQueryRepository에서 admin DTO 의존성 제거
- 도메인 레이어 전용 MemberProjection DTO 생성
- MemberQueryRepository/Impl이 MemberProjection을 반환하도록 변경
- MemberResponse에 from(MemberProjection) 팩터리 메서드 추가
- MemberManagementService에서 MemberProjection → MemberResponse 변환 로직 적용
- 관련 테스트 MemberProjection 기반으로 수정
* feat: 제출 지원서 조회 응답에 요건에 맞게 필드 추가
- 지원자 신분(careerDetails), 모집 단위(recruitType) 응답에 추가
* test: RecruitType 필터링 지원 조회 테스트 추가
- AdminApplyQueryRepositoryTest 필터링 시나리오 보강
- AdminTempApplyServiceTest 임시저장 지원서 필터링 시나리오 보강
* refactor: 임시저장 지원서(Temp Apply) 관련 로직 초기 버전으로 롤백
* fix: 임시 저장된 지원서 목록 페이징 일관성 유지 (size=10, createdAt 역순)
* test: MemberQueryRepositoryTest의 semesterName 검증식을 MemberProjection 반환 형식에 맞게 수정 (CI 실패 해결)
* feat: 제출된 지원서 조회 응답 필드 수정 (기획 요구사항 반영)
- 노출 항목 최적화 (이름, 연락처, 이메일, 포지션,
지원자 신분, 모집 단위, 활동 상태, 비고)
- 상세 이력(ApplicationForm) 응답에서 제외
* feat: 지원서 비고(note) 필드 추가 및 응답 반영
- Apply 엔티티에 note 추가 (Builder.Default 포함)
- V21__add_note_to_apply 플라이웨이 마이그레이션 파일 추가
- SubmittedApplyResponse 응답에서 note 필드 매핑 및 불필요 항목 제거
* chore: VPC 내부망 통신을 위한 Redis SSL 설정 제거 (#459)
* refactor: 제출 완료된 지원서 삭제 로직 품질 개선 (#460)
* refactor: SubmittedApplyService 불필요한 메서드 제거 및 코드 개선
- ensureSubmitted() 제거: repository에서 Status.SUBMITTED 조건으로 이미 필터링하므로 중복 검증
- deleteProfileAndApplicationForm() 제거: 단순 2줄 위임 메서드를 호출부에 인라이닝
- toSubmittedApplyResponse() 제거: SubmittedApplyResponse::from 메서드 참조로 인라이닝
- validateQuestions() Stream forEach 안티패턴 수정: findAny().ifPresent()로 교체
- 중복 및 미사용 import 제거 (SubmittedApplyCountResponse, QuestionErrorCode, QuestionException)
* test: SubmittedApplyServiceTest 정리 및 테스트 케이스 추가
- 중복 import 제거 (SubmittedApplyCountResponse)
- 중복 테스트 메서드 제거 (제출된_지원서_수_조회_성공, 제출된_지원서가_없을_때_0_반환)
- 제출되지_않은_지원서_수정시_예외_발생 제거: ensureSubmitted 제거로 불가능한 시나리오
- 제출된_지원서_여러건_삭제시_중복_ID는_한_번만_처리 테스트 추가
- 테스트 메서드명 및 반환값 검증 개선
* fix: SubmittedApplyController에서 중복된 import 문 제거
* feat: 제출된 지원서 불합격 처리 시 REJECTED 상태 전환
- Apply.Status에 REJECTED 추가
- Apply.reject() 도메인 메서드 추가: applicationForm null 처리 + status REJECTED 전환
- SubmittedApplyService: deleteApplicationForm() 직접 호출 -> reject()으로 교체
- V22 마이그레이션: REJECTED 상태 추가 이력 문서화 (varchar 컬럼이므로 DDL 변경 불필요)
- SubmittedApplyServiceTest: 삭제 후 status REJECTED 검증 추가
* feat: 지원서 상세 조회 기능 추가 (Issue #454) (#458)
* feat: [FUNC_APL_MGT_02] 지원서 상세 조회 기능 구현
* feat: 상세 조회 설문 및 포트폴리오 항목 주석 처리
* feat: 임시 지원서 지원서 조회 기능 개선 및 요구사항 적용 (#470)
* feat: Apply 상태를 ApplyStatus로 변경하여 코드 일관성 강화
* feat: SubmittedApplyResponse를 AdminApplyResponse로 변경
* feat: ApplyStatus 매개변수를 추가하여 로직 일관
* feat: countSubmittedApply 메서드 삭제
* feat: 관리자 지원서 관리로 통일
* feat: TempSavedApply의 목록 조회 기능 제
* feat: 임시 저장된 지원서 조회 테스트 이관
* feat: Admin Apply API 태그 설명 수정
* feat: 삭제된 임시 신청서에 대한 오류 메시지 업데이트
* feat:관리자 로그아웃 기능 구현 (#472)
* feat:관리자 로그아웃 기능 구현
* fix:주석 추가
* fix:불필요한 구문 삭제
* feat: 임시 저장된 지원서 상세 조회 기능 개선 및 요구사항 적용 (#473)
* feat: 지원서 상세 조회 기능 개선 및 applyStatus 파라미터 추가
Spring Boot 3(Spring Framework 6+)에서는 컴파일 시 -parameters 플래그가 기본으로 활성화되어 있어, 런타임에 메서드 파라미터 이름이 보존됩니다. 따라서 파라미터 이름(applyId)과 경로 변수 이름({applyId})이 동일한 경우, @PathVariable("applyId")처럼 명시적으로 값을 지정할 필요가 없습니다.
* feat: 지원서 상세 조회 기능 추가 및 응답 DTO 개선
관리자가 지원서의 상세 정보를 조회할 수 있는 기능을 추가하고,
응답 DTO를 개선하여 지원자의 지역, 경력 기간, 관심 분야를 포함했습니.
* feat: 지원서 조회 관련 메서드 이름 변경 및 설명 수정
- AdminApplyController.java에서 지원서 목록 조회와 상세 조회의 메서드 이름을 변경하였습니다.
- 지원서 목록 조회의 설명을 간결하게 수정하였습니다.
* test: 테스트 클래스 이름 변경 및 응답 DTO 수정
SubmittedApplyServiceTest.java
- AdminApplyServiceTest.java로 이름 변경
- 응답 DTO를 AdminApplyDetailResponse로 수정
- 메서드 호출 시 적용 상태를 명시적으로 전달하도록 변경
* feat: 로직을 개선하면서 사용하지 않는 DTO 제거
* feat: 지원서 상세 응답 DTO 수정
AdminApplyDetailResponse에서 사용하지 않는 파라미터를 제거하여
응답 DTO를 간소화하였습니다.
AdminApplyService에서 해당 변경 사항에 맞게 메서드를 수정하였습니다.
* feat: 지원서 상세 조회 기능에 동적쿼리
- ApplyStatus가 null인 경우에 대해서 처리하기 위해 querydsl로 동적쿼리 구
* style: 지원서 조회 메서드 이름 변경
* feat: 지원서 상세조회 기능 개선
- 지원서 상세조회 테스트에서 applyRepository를 adminApplyQueryRepository로 변경
- 다양한 지원서 상태(TEMP_SAVED, REJECTED, JOINED)에 대한 상세조회 테스트 추가
- 상태가 null일 때의 상세조회 및 예외 발생 테스트 추가
* feat: 지원서 상세조회 응답 수정
응답 DTO를 개선하여 가독성을 높이고, 코드의 일관성을 유지하기 위해
toSubmittedApplyDetailResponse 메서드를 AdminApplyDetailResponse::from으로 변경하였습니다.
* feat: 임시 저장된 지원서 삭제 기능 개선 및 요구사항 적용 (#479)
* feat: 지원서 상세 조회 응답 구조 및 개
* fix: 지원서 상세 정보 응답 flatten 처
* feat: 관리자 지원서 관리 API 리팩토링 및 서비스 개선
불필요한 메서드를 제거하여 코드의 간결성을 제고했습니다.
* test: applyId 검증 로직 수정
getFirst() 메서드를 사용하여 첫 번째 요소를 명확하게 가져오도록 변경했습니다.
* chore: TestContainers 버전 업데이트
TestContainers의 BOM 버전을 1.20.4에서 2.0.2로 업데이트했습니다.
이 변경은 최신 기능과 버그 수정을 반영하여 테스트 환경을 개선하기 위함입니다.
* feat: 지원서 상세 조회 응답 구조 및 개선
* fix: 지원서 상세 정보 응답 flatten 처리
* feat: 관리자 지원서 관리 API 리팩토링 및 서비스 개선
불필요한 메서드를 제거하여 코드의 간결성을 제고했습니다.
* test: applyId 검증 로직 수정
getFirst() 메서드를 사용하여 첫 번째 요소를 명확하게 가져오도록 변경했습니다.
* chore: TestContainers 버전 업데이트
TestContainers의 BOM 버전을 1.20.4에서 2.0.2로 업데이트했습니다.
이 변경은 최신 기능과 버그 수정을 반영하여 테스트 환경을 개선하기 위함입니다.
* refactor: 지원서 삭제 로직 개선 및 소프트 삭제 추가
지원서 삭제 API의 로직을 리팩토링하여, 제출된 지원서를
삭제할 때 reject 및 프로필 삭제 대신 소프트 삭제를
적용하도록 변경했습니다. 이를 통해 데이터 무결성을
유지하면서도 삭제된 지원서를 관리할 수 있게 되었습니다.
추가로, 데이터베이스에 soft delete를 위한 is_deleted
컬럼을 추가했습니다.
* chore: TestContainers 버전 원상 복구
* refactor: AdminApplyService에서 쿼리 리포지토리 변경
AdminApplyService에서 AdminApplyQueryRepository를 AdminApplyRepository로 변경하였습니다.
이 변경은 코드의 일관성을 높이고, 리포지토리 사용을 단순화하기 위한 것입니다.
또한, 테스트 코드에서 delete 메서드를 deleteAll로 변경하여
여러 개의 지원서를 한 번에 삭제할 수 있도록 개선하였습니다.
* refactor(test): AdminApplyQueryRepositoryTest에서 쿼리 리포지토리 변경
AdminApplyQueryRepository를 AdminApplyRepository로 변경하여
테스트 코드의 일관성을 높였습니다. 이 변경은 기능에 영향을
주지 않으며, 코드 가독성을 개선합니다.
* style: AdminApplyDetailResponse.java 파일의 끝에 개행 추가
파일의 끝에 개행이 없던 문제를 수정하여 코드 스타일을 개선했습니다.
이로 인해 코드의 가독성이 향상되고, 일부 도구와의 호환성 문제가 해결됩니다.
* feat: 임시 저장된 지원서 삭제 기능 제거
임시 저장 상태의 지원서를 단건 삭제하는 기능에 대한
테스트를 추가했습니다. 이 테스트는 지원서가
정상적으로 삭제되는지 검증하며, 삭제 요청 시
해당 지원서를 찾고 삭제하는 로직을 확인합니다.
* feat: 지원서 제출 동시성 이슈 해결 (비관적 락 적용)
* Revert "Merge pull request #481 from JECT-Study/feat/issue-480-submit-lock"
This reverts commit f8b8d16, reversing
changes made to 7b66ecf.
* feat:관리자 로그인 구현 (#503)
* feat: 관리자 로그인 API 기능 구현
* feat: 관리자 로그인 API 테스트 코드 작성
* feat: 임시 지원서 지원서 조회 기능 개선 및 요구사항 적용 (#470)
* feat: Apply 상태를 ApplyStatus로 변경하여 코드 일관성 강화
* feat: SubmittedApplyResponse를 AdminApplyResponse로 변경
* feat: ApplyStatus 매개변수를 추가하여 로직 일관
* feat: countSubmittedApply 메서드 삭제
* feat: 관리자 지원서 관리로 통일
* feat: TempSavedApply의 목록 조회 기능 제
* feat: 임시 저장된 지원서 조회 테스트 이관
* feat: Admin Apply API 태그 설명 수정
* feat: 삭제된 임시 신청서에 대한 오류 메시지 업데이트
* feat:관리자 로그아웃 기능 구현 (#472)
* feat:관리자 로그아웃 기능 구현
* fix:주석 추가
* fix:불필요한 구문 삭제
* feat: 임시 저장된 지원서 상세 조회 기능 개선 및 요구사항 적용 (#473)
* feat: 지원서 상세 조회 기능 개선 및 applyStatus 파라미터 추가
Spring Boot 3(Spring Framework 6+)에서는 컴파일 시 -parameters 플래그가 기본으로 활성화되어 있어, 런타임에 메서드 파라미터 이름이 보존됩니다. 따라서 파라미터 이름(applyId)과 경로 변수 이름({applyId})이 동일한 경우, @PathVariable("applyId")처럼 명시적으로 값을 지정할 필요가 없습니다.
* feat: 지원서 상세 조회 기능 추가 및 응답 DTO 개선
관리자가 지원서의 상세 정보를 조회할 수 있는 기능을 추가하고,
응답 DTO를 개선하여 지원자의 지역, 경력 기간, 관심 분야를 포함했습니.
* feat: 지원서 조회 관련 메서드 이름 변경 및 설명 수정
- AdminApplyController.java에서 지원서 목록 조회와 상세 조회의 메서드 이름을 변경하였습니다.
- 지원서 목록 조회의 설명을 간결하게 수정하였습니다.
* test: 테스트 클래스 이름 변경 및 응답 DTO 수정
SubmittedApplyServiceTest.java
- AdminApplyServiceTest.java로 이름 변경
- 응답 DTO를 AdminApplyDetailResponse로 수정
- 메서드 호출 시 적용 상태를 명시적으로 전달하도록 변경
* feat: 로직을 개선하면서 사용하지 않는 DTO 제거
* feat: 지원서 상세 응답 DTO 수정
AdminApplyDetailResponse에서 사용하지 않는 파라미터를 제거하여
응답 DTO를 간소화하였습니다.
AdminApplyService에서 해당 변경 사항에 맞게 메서드를 수정하였습니다.
* feat: 지원서 상세 조회 기능에 동적쿼리
- ApplyStatus가 null인 경우에 대해서 처리하기 위해 querydsl로 동적쿼리 구
* style: 지원서 조회 메서드 이름 변경
* feat: 지원서 상세조회 기능 개선
- 지원서 상세조회 테스트에서 applyRepository를 adminApplyQueryRepository로 변경
- 다양한 지원서 상태(TEMP_SAVED, REJECTED, JOINED)에 대한 상세조회 테스트 추가
- 상태가 null일 때의 상세조회 및 예외 발생 테스트 추가
* feat: 지원서 상세조회 응답 수정
응답 DTO를 개선하여 가독성을 높이고, 코드의 일관성을 유지하기 위해
toSubmittedApplyDetailResponse 메서드를 AdminApplyDetailResponse::from으로 변경하였습니다.
* feat: 임시 저장된 지원서 삭제 기능 개선 및 요구사항 적용 (#479)
* feat: 지원서 상세 조회 응답 구조 및 개
* fix: 지원서 상세 정보 응답 flatten 처
* feat: 관리자 지원서 관리 API 리팩토링 및 서비스 개선
불필요한 메서드를 제거하여 코드의 간결성을 제고했습니다.
* test: applyId 검증 로직 수정
getFirst() 메서드를 사용하여 첫 번째 요소를 명확하게 가져오도록 변경했습니다.
* chore: TestContainers 버전 업데이트
TestContainers의 BOM 버전을 1.20.4에서 2.0.2로 업데이트했습니다.
이 변경은 최신 기능과 버그 수정을 반영하여 테스트 환경을 개선하기 위함입니다.
* feat: 지원서 상세 조회 응답 구조 및 개선
* fix: 지원서 상세 정보 응답 flatten 처리
* feat: 관리자 지원서 관리 API 리팩토링 및 서비스 개선
불필요한 메서드를 제거하여 코드의 간결성을 제고했습니다.
* test: applyId 검증 로직 수정
getFirst() 메서드를 사용하여 첫 번째 요소를 명확하게 가져오도록 변경했습니다.
* chore: TestContainers 버전 업데이트
TestContainers의 BOM 버전을 1.20.4에서 2.0.2로 업데이트했습니다.
이 변경은 최신 기능과 버그 수정을 반영하여 테스트 환경을 개선하기 위함입니다.
* refactor: 지원서 삭제 로직 개선 및 소프트 삭제 추가
지원서 삭제 API의 로직을 리팩토링하여, 제출된 지원서를
삭제할 때 reject 및 프로필 삭제 대신 소프트 삭제를
적용하도록 변경했습니다. 이를 통해 데이터 무결성을
유지하면서도 삭제된 지원서를 관리할 수 있게 되었습니다.
추가로, 데이터베이스에 soft delete를 위한 is_deleted
컬럼을 추가했습니다.
* chore: TestContainers 버전 원상 복구
* refactor: AdminApplyService에서 쿼리 리포지토리 변경
AdminApplyService에서 AdminApplyQueryRepository를 AdminApplyRepository로 변경하였습니다.
이 변경은 코드의 일관성을 높이고, 리포지토리 사용을 단순화하기 위한 것입니다.
또한, 테스트 코드에서 delete 메서드를 deleteAll로 변경하여
여러 개의 지원서를 한 번에 삭제할 수 있도록 개선하였습니다.
* refactor(test): AdminApplyQueryRepositoryTest에서 쿼리 리포지토리 변경
AdminApplyQueryRepository를 AdminApplyRepository로 변경하여
테스트 코드의 일관성을 높였습니다. 이 변경은 기능에 영향을
주지 않으며, 코드 가독성을 개선합니다.
* style: AdminApplyDetailResponse.java 파일의 끝에 개행 추가
파일의 끝에 개행이 없던 문제를 수정하여 코드 스타일을 개선했습니다.
이로 인해 코드의 가독성이 향상되고, 일부 도구와의 호환성 문제가 해결됩니다.
* feat: 임시 저장된 지원서 삭제 기능 제거
임시 저장 상태의 지원서를 단건 삭제하는 기능에 대한
테스트를 추가했습니다. 이 테스트는 지원서가
정상적으로 삭제되는지 검증하며, 삭제 요청 시
해당 지원서를 찾고 삭제하는 로직을 확인합니다.
* feat: 지원서 제출 동시성 이슈 해결 (비관적 락 적용)
* Revert "Merge pull request #481 from JECT-Study/feat/issue-480-submit-lock"
This reverts commit f8b8d16, reversing
changes made to 7b66ecf.
* feat:관리자 로그인 구현
* feat:관리자 로그인 실패 카운트 예외 처리 추가
* refactor:더이상 사용하지 않는 코드 정리
* refactor:더이상 사용하지 않는notification 관련 코드 삭제
* fix:Rebase 충돌 수정
---------
Co-authored-by: 023 <rhdgmltkd88@gmail.com>
Co-authored-by: 023-dev <0_2_3@naver.com>
* feat: Redis SSL 연결 설정 추가 (#505)
RedisConnectionConfig.java에 SSL 연결을 위한 설정을 추가했습니다.
이제 Redis 연결 시 SSL 사용 여부를 설정할 수 있으며,
application.properties 파일에서 spring.data.redis.ssl.enabled 값을 통해
SSL 사용을 제어할 수 있습니다.
* feat: 직군별 단건 조회 최적화 및 캐싱 적용 (#510)
* feat: 단건 조회 최적화 및 캐싱 적용 (#507)
* fix: Recruit 이벤트 핸들러에 activeRecruit 캐시 무효화 로직 추가
* fix: Recruit 단건 조회 시 비어있는 Optional(null)에 대한 캐싱 방지 로직(unless) 추가
* fix: Optional 반환 시 스프링 캐시 추상화의 언랩핑(Unwrapping)으로 인한 SpEL null 참조 예외 해결 (unless = "#result == null")
* test: 통합 테스트(ApplicationPeriodTest) 환경에서 모킹된 RedisConnectionFactory의 NullPointerException 방지를 위해 캐시 비활성화(spring.cache.type=none) 추가
* test: ApplicationPeriodTest 내 모킹된 RedisConnectionFactory의 명시적 Stubbing 추가를 통해 캐시 매니저(DefaultRedisCacheWriter)의 NullPointerException 방지 및 테스트 안정성 확보
* fix: 테스트 환경 캐시 매니저 분리(TestCacheConfig) 및 fetchJoin 불완전 로딩 위험 제거
- TestCacheConfig 생성: ConcurrentMapCacheManager로 RedisCacheManager 오버라이드
- ApplicationPeriodTest에 @import(TestCacheConfig.class) 적용
- RecruitQueryRepositoryImpl에서 불필요한 leftJoin().fetchJoin() 제거
(fetchFirst()의 LIMIT 1이 row 레벨에서 적용되어 questions 컬렉션 불완전 로딩 위험)
* fix: fetchJoin + fetchOne 조합으로 questions N+1 방지 및 LIMIT 1 컬렉션 절단 해결, BeanDefinitionOverrideException 해결
- fetchFirst() → fetchOne()으로 변경: LIMIT 1이 row 레벨에서 적용되어 JOIN 결과가 절단되는 문제 해결
- leftJoin(questions).fetchJoin() 복원: questions 컬렉션 Eager 로딩으로 N+1 방지
- ApplicationPeriodTest에 spring.main.allow-bean-definition-overriding=true 추가
* fix: RedisConnectionFactory Deep Stubs 적용으로 테스트 컨텍스트 로딩 시 NPE 근본 해결
- 기존 접근: TestCacheConfig + @import + bean-overriding → 실패 (빈 등록 순서/오버라이드 문제)
- 근본 원인: @MockitoBean의 기본 answer(RETURNS_DEFAULTS)로 인해
connectionFactory.getConnection()이 null 반환 → DefaultRedisCacheWriter NPE
- 해결: @MockitoBean(answers = Answers.RETURNS_DEEP_STUBS) 적용
→ getConnection()이 자동으로 Mock RedisConnection 반환
→ 체이닝 호출도 모두 Mock으로 처리되어 캐시 miss로 동작
- 불필요해진 TestCacheConfig.java 삭제
* fix: 지원서 제출 동시성 이슈 해결 (#482)
* feat: 지원서 제출 동시성 이슈 해결 (비관적 락 적용)
* refactor: 동시성 테스트 코드를 PR 설명으로 이동하고 테스트 파일 삭제
* refactor: MySQL 호환성을 위해 ApplyRepository에서 불필요한 QueryHints 제거
* feat: Redis SPOF 방어를 위한 Circuitbreaker 적용 (#511)
* chore: Resilience4j Circuit Breaker 및 AOP 의존성 추가
* feat: 캐시 장애 대응 서킷 브레이커 및 우회 처리 기능 구현
Resilience4j 기반 Redis 캐시 서킷 브레이커 AOP, 에러 핸들러, 캐시 우회 컨텍스트,
CacheResolver를 구현하여 캐시 장애 시 자동으로 캐시 접근을 우회하도록 개선했습니다.
* feat: CachingConfigurer 구현으로 장애 대응 캐시 전략 적용
RedisCacheConfig에 ResilientCacheErrorHandler와 ResilientCacheResolver를 적용하여
Redis 장애 발생 시 캐시 예외를 삼키고, 서킷 오픈 시 NoOpCache로 전환하도록 구현했습니다.
이를 통해 캐시 장애 시에도 비즈니스 로직이 DB 폴백을 수행할 수 있도록 개선했습니다.
* chore: Resilience4j 의존성 버전 및 패키지 변경
* feat: 복합 캐시 어노테이션(@caching) 및 중첩된 컨텍스트 처리 추가
@caching 어노테이션을 지원하도록 AOP 로직을 개선하고, 캐시 우회 설정을 스택 기반 컨텍스트로 변경하여 중첩된 호출에서도 상태를 정확히 처리할 수 있도록 수정했습니다.
* refactor: RedisCacheExceptionClassifier 리팩토링 및 코드 간소화
- lombok @UtilityClass로 변경하여 유틸리티 클래스 구현 단순화
- 인프라 장애 판별 로직 명확화 및 예외 클래스 체크 범위 조정
* feat: 스택 기반 캐시 컨텍스트 처리 방식으로 개선 및 ThreadLocal 관리 최적화
- 기존 boolean 플래그를 스택(Deque) 구조로 대체하여 중첩된 캐시 호출 지원
- @UtilityClass 적용으로 유틸리티 클래스 단순화
- ThreadLocal 누수 방지를 위해 실행 컨텍스트 관리 로직 정비
- Redis 장애 캐시 처리 및 호출 상태 관리 개선
* refactor: ResilientCacheResolver 리팩토링 및 @requiredargsconstructor 적용
- 생성자 lombok @requiredargsconstructor로 교체하여 코드 간소화
- 주석을 추가 및 수정해 동작 방식 명확히 설명
- 불필요한 생성자 삭제 및 가독성 향상
* feat: Redis 장애 시 DB 폴백 및 서킷 브레이커 동작 검증용 통합 테스트 추가
- Redis 장애 시 캐시 폴백 및 데이터 조회 검증 테스트 작성
- CacheErrorHandler의 예외 처리 케이스 추가, 비인프라 예외 직렬화 테스트 포함
- RedisTestContainersConfig에 Redis 중단/재시작 유틸리티 메서드 추가
* refactor: ResilientCacheErrorHandler 주석 리팩토링 및 예외 처리 로직 보강
- 주석을 한글로 수정 및 추가하여 코드 이해도 향상
- 캐시 쓰기 작업 시 Redis 장애 발생 시 데이터 정합성을 보장하기 위한 예외 처리 로직 추가
- 그 외 주석 및 로깅 메시지를 명확하게 개선하여 유지보수성을 증대
* refactor: RedisCacheCircuitBreakerConfig 및 Provider 주석 리팩토링
- 주석을 한글로 수정 및 추가하여 코드 이해도 및 가독성 향상
- 서킷 브레이커 설정과 관리 로직의 동작 방식을 명확히 설명
* refactor: 캐시 어노테이션 처리 로직 및 주석 리팩토링
- 메서드뿐 아니라 클래스 레벨의 캐시 어노테이션 처리 추가
- @caching 복합 어노테이션 처리 로직 개선 및 중복 코드 제거
- ThreadLocal 관리 로직 및 컨텍스트 정리 주석 보강
- RedisCacheCircuitBreakerAspect 코드 가독성 및 유지보수성 향상
* refactor: 캐시 실패 상태 관리 스택 구조로 개선
- FAILED_CACHES 대신 FAILED_CACHES_STACK 사용하여 컨텍스트 수준별 독립 관리 구현
- ThreadLocal 누수 방지를 위한 실패 상태 관리 로직 최적화
- 캐시 실패 처리 및 참조 메서드의 정확성 향상
* feat: 서킷 브레이커 리셋 기능 추가 및 테스트 간 상태 격리 개선
- RedisCacheCircuitBreakerProvider에 `resetAll` 메서드 추가
- 통합 테스트에서 서킷 브레이커 메트릭 초기화로 테스트 간 영향 제거
- CacheFallbackIntegrationTest에 상태 초기화 및 검증 로직 추가
* refactor: 캐시 어노테이션 주석 및 처리 로직 간소화
- 스프링 캐시 어노테이션에 대한 주석 수정 및 표현 단순화
- 불필요한 주석 제거로 코드 가독성 개선
- CircuitBreakerExecution record 정의 간소화
* feat: CacheFallbackIntegrationTest 개선 및 데이터 격리 강화
- @transactional 추가로 테스트 데이터 격리 보장
- 테스트 데이터에 uniqueSuffix 적용으로 중복 방지
- 관련 엔터티 생성 로직 개선 및 유연성 향상
* refactor: RedisCacheCircuitBreakerAspect 캐시 추상화 처리 간소화
- CacheOperationSource 활용으로 캐시 이름 추출 로직 단순화
- 중복 및 비효율적인 캐시 설정 탐색 로직 제거
- 코드 가독성 및 유지보수성 개선
* feat: 쓰기 작업(strict write) 모드 추가 및 캐시 실행 컨텍스트 확장
- ThreadLocal에 STRICT_WRITE_STACK 추가하여 쓰기 작업 실패 시 예외 처리를 제어
- pushContext 메서드에 strictWrite 파라미터 추가로 호출 수준별 설정 지원
- CacheOperation 분석을 통해 read-only와 쓰기 작업 구분, 엄격 모드 활성화 조건 반영
- ResilientCacheErrorHandler에서 쓰기 작업 실패 시 strict write 설정에 따라 예외 처리
- 관련 메서드와 로직의 주석 강화 및 가독성 개선
* feat: 서킷 브레이커 및 Redis 장애 처리 로직 추가
- AccessPeriodVerifier에 Resilience4j CircuitBreaker 통합
- Redis 장애 시 폴백 로직 및 장애 전파 방지 처리 추가
- CircuitBreaker 상태 기반 접근 제어 및 실패 기록 강화
- Redis 장애 시 안전한 우회 모드 도입 및 장애 컨텍스트 마킹
- 주요 로깅 및 예외 처리 로직 개선
* test: AccessPeriodVerifierTest에 CircuitBreaker 관련 의존성 및 테스트 로직 추가
- RedisCacheCircuitBreakerProvider와 CircuitBreaker 모의(Mock) 객체 추가
- CircuitBreaker 동작을 검증하기 위한 setUp 및 관련 테스트 로직 보강
* style: 주석 수정
* refactor: 중복 로직 리팩토
* style: 불필요한 주석 제거 및 코드 정리
- RedisCacheCircuitBreakerConfig에서 불필요한 주석 제거로 가독성 개선
* refactor: 불필요한 주석 제거 및 코드 가독성 개선 in CacheCircuitBreakerAspect
* refactor: RedisCacheConfig 오류 핸들러의 주석 간소화
* refactor: ResilientCacheErrorHandler 주석 간소화
* refactor: remove redundant `final` modifier from RedisCacheExceptionClassifier
* refactor: remove unnecessary comment in RedisCacheCircuitBreakerProvider
* refactor: Bulk Delete(Update) 로직 성능 최적화 (#515)
* refactor: `AdminApplyService` 리팩토링 및 `AdminApplyRepository` 수정
- `findByIdAndStatusWithMember` 메서드를 `AdminApplyRepository`로 이동.
- 삭제 로직에서 중복 검증 제거 및 `deleteAllByIds` 메서드로 개선.
- 테스트 코드에서 서비스 명칭(`submittedApplyService` → `adminApplyService`) 변경 및 메서드 수정 반영.
- 필요 없는 Mock 객체 및 메서드 호출 제거로 테스트 정리.
* refactor(admin): 관리자 구성원 관리 API 리팩토링
구성원 관리 API의 컨트롤러 및 서비스 클래스를 리팩토링하여
명확한 역할 분리를 구현했습니다. 기존의 MemberManagementService와
MemberManagementController를 AdminMemberService와
AdminMemberController로 변경하여 관리 기능을 명확히 했습니다.
* refactor: `MemberQueryRepository` 및 `MemberQueryRepositoryImpl` 리팩토링
`MemberQueryRepository`에서 사용하지 않는 메서드를 제거하고,
`MemberQueryRepositoryImpl`에서 불필요한 임포트를 정리했습니다.
* refactor(admin): AdminMemberService의 deprecated 주석 수정
AdminMemberService.java에서 TeamMember.jobFamily 동기화 관련
주석을 수정하였습니다. @deprecated 어노테이션의 세부 사항을
간소화하여 코드 가독성을 향상시키고, 향후 제거될 가능성을
명시하였습니다.
* test(admin): AdminApplyService의 삭제 관련 테스트 수정 및 추가
* refactor(test): 회원 목록 조회 테스트 코드 정리
회원 목록 조회 관련 테스트에서 불필요한 테스트 케이스를 제거하고,
코드 가독성을 높이기 위해 일부 테스트 메서드를 정리했습니다.
이로 인해 테스트 유지보수가 용이해질 것입니다.
* refactor(admin): 지원서 삭제 로직 간소화
지원서 삭제 시 중복 ID 처리 및 예외 발생 로직을 제거하여
코드를 간소화했습니다. 이제 중복 ID는 한 번만 처리되며,
존재하지 않는 ID에 대한 예외는 더 이상 발생하지 않습니다.
* refactor: 다중 회원 삭제 로직 간소화
회원 삭제 시 중복 ID를 처리하는 로직을 제거하고, 직접적으로 adminMemberRepository의 deleteAllByIds 메서드를 호출하도록 변경했습니다.
* refactor(admin): 구성원 추가 및 수정 API의 메서드 정리
구성원 추가와 수정 API의 메서드 이름을 명확하게 변경했습니다.
이로 인해 코드의 가독성이 향상되고, 각 메서드의 역할이 더 분명해졌습니다.
* refactor(admin): 페이지 응답의 총 개수 처리 로직 수정
페이지 응답을 생성할 때, 총 개수가 null인 경우 0으로 설정하도록
로직을 수정했습니다. 이를 통해 페이지네이션 처리 시 발생할 수 있는
예외 상황을 방지하고, 안정성을 높였습니다.
* feat:백오피스 관련 역할 권한 추가 (#514)
* refactor:운영, 서포터즈 역할 및 권한 추가
* refactor:관리자 로그인 관련 Component 로직 method명 변경
* refactor:Role 파일 개선
* refactor:Permission 불변 객체로 수정
* refactor:상수 직접 호출로 변경
* add:테스트 코드 작성
* feat: role enum field 추가
* refactor(apply): 지원서 제출 동시성 제어를 비관적 락에서 낙관적 락으로 전환 (#524)
* refactor(apply): 지원서 제출 동시성 제어를 비관적 락에서 낙관적 락으로 전환
- Apply 엔티티에 @Version 필드 추가
- ApplyRepository에서 PESSIMISTIC_WRITE 락 메서드 제거
- ApplyService.submitApplication()에서 낙관적 락 충돌 시 ALREADY_SUBMITTED 예외 변환
- @SQLDelete에 version 조건 추가
- Flyway V25 마이그레이션으로 version 컬럼 추가
- 관련 테스트 업데이트
* refactor(apply): soft delete 시 version 증가 로직 추가 (CodeRabbit 리뷰 반영)
* refactor(apply): submitApplication에 명시적 flush 추가 (CodeRabbit 리뷰 반영)
- 트랜잭션 커밋 시점이 아닌 메서드 내부에서 낙관적 락 예외를 처리하기 위해 flush() 호출 추가
* feat(mail): 관리자 메일 템플릿 관리 기능 추가 (#523)
* feat(mail): add admin mail scenario management
* feat(build): Apache Commons Text 라이브러리 추가
프로젝트에서 문자열 처리를 위한 Apache Commons Text 라이브러리를
추가했습니다.
* test(AdminMailScenarioController): CORS 설정 추가 및 테스트 수정
테스트 환경에서 CORS 정책을 설정하기 위해 AdminMailScenarioControllerTest에 TestPropertySource를 추가했습니다. 이로 인해 테스트가 올바르게 실행될 수 있도록
CORS 관련 속성을 정의했습니다.
* test(AdminMailScenarioController): 테스트 환경 설정 리팩토링
Mockito를 사용하여 AdminMailScenarioController의 테스트를 리팩토링했습니다.
기존의 @WebMvcTest 어노테이션을 제거하고, MockitoExtension을 사용하여 MockMvc 인스턴스를 수동으로 설정하도록 변경했습니다.
* feat(mail): 중복 시나리오 코드 예외 처리 로직 추가
메일 시나리오 생성 및 업데이트 시, 데이터베이스의 unique 제약 조건 위반을
서비스 계층에서 도메인 예외로 변환하는 로직을 추가했습니다.
이로 인해 중복 시나리오 코드 발생 시, 적절한 예외가 발생하도록 개선되었습니다.
test(mail): 중복 시나리오 코드 예외 처리 테스트 추가
메일 시나리오 생성 및 업데이트 시, 중복 시나리오 코드로 인한 예외가
정상적으로 처리되는지 검증하는 테스트 케이스를 추가했습니다.
동시 요청으로 인한 race condition 상황을 시뮬레이션하여
예외가 올바르게 발생하는지 확인합니다.
fix(mail): null 변수 처리 로직 개선
메일 템플릿 엔진에서 null 변수가 전달될 경우에도
예외 없이 템플릿을 반환하도록 로직을 수정했습니다.
이로 인해 null 안전성을 높이고, 템플릿 처리의 일관성을
유지할 수 있게 되었습니다.
* feat(mail): 개인 변수 '기수'를 'SEMESTER'로 변경
MailVariable.java에서 '기수'라는 개인 변수를 'SEMESTER'로 수정하였습니다.
* feat(mail): 메일 시나리오 카테고리 및 타입 추가
메일 시나리오에 카테고리와 타입을 추가하여, 시나리오의 분류를 명확히 하였습니다.
변경된 사항:
- MailScenario, MailScenarioRequest, MailScenarioResponse에 카테고리 및 타입 필드 추가
- 관련 테스트 코드 수정
* feat(mail): 메일 시나리오 코드 수정 및 타입 변경
메일 시나리오 테스트에서 'MAKERS_FIRST_PASS'를 'MAKERS_TEMP_PASS'로 수정하였습니다.
* feat(mail): 메일 시나리오 코드 수정 및 타입 변경
메일 시나리오 테스트에서 'MAKERS_FIRST_PASS'를 'MAKERS_TEMP_PASS'로 수정하였습니다.
* feat(mail): 메일 시나리오 테스트 코드 수정 및 변수 변경
메일 시나리오 테스트에서 사용되는 변수 이름을 'NAME'에서 'name'으로 변경하였습니다.
* feat(mail): 메일 시나리오 테스트 코드 수정 및 변수 변경
메일 시나리오 테스트에서 사용되는 변수 이름을 'NAME'에서 'name'으로 변경하였습니다.
* chore: add missing untracked files for mail refactoring
* fix: add missing sendEmail method to email service
* test: add mail scenario failure cases
* chore: exclude mail dispatch files from PR scope
* refactor(application): JPA Auditing 비활성화
SupportApplication에서 @EnableJpaAuditing 어노테이션을 제거했습니다.
* refactor(mail): squash V24~V29 migrations into one unified schema script
* fix(mail): align MailScenarioVariable label column name with V24 db schema
* refactor(mail): remove duplicate db constraint check and redundant saveAndFlush
* feat: 시나리오 변수 삭제 검증 강화 및 에러 메시지 상세화 (복수 변수 지원)
* feat:백오피스의 관리자 계정 추가하기 기능 구현 (#525)
* feat:관리자 계정 추가 기능 구현
* add:테스트 코드 작성
* feat:관리자 Role 업데이트 기능 구현 (#526)
* feat:관리자 Role 업데이트 기능 구현
* fix: 주석 통일
* refactor:백오피스 사용자 권한 확인 로직 통합
* fix:테스트 코드 보완
* refactor:role update 로직 수정
* remove:필요없는 테스트 삭제
* feat:관리자 계정 활성화/비활성화 기능 추가 (#527)
* feat:관리자 계정 활성화/비활성화 기능 추가
* feat:본인을 비활성화 가드 로직 추가
* feat:비활성화 계정 차단 로직 추가
* feat:관리자 계정 수정하기 구현 (#528)
* feat:관리자 계정 수정하기 구현
* feat:자신의 계정에 대한 권한 수정 차단
* feat: 모집 공고 타입 기본 모델 확장 (#531)
* Prepare recruitment typing for expanded official postings
The recruitment expansion plan needs new public recruitment categories before follow-up PRs can add detail fields, member typing, and recruitId-based flows. This keeps legacy enum values intact while adding the new official recruitment types as a backward-compatible base.
Constraint: PRs are intentionally limited to about 300 changed lines including tests
Rejected: Rename existing REGULAR/BACKFILL values now | would require migration and broaden this PR
Confidence: high
Scope-risk: narrow
Directive: Do not remove legacy RecruitType values until migration PRs provide explicit data mapping
Tested: ./gradlew test --tests org.ject.support.domain.recruit.domain.RecruitTypeTest -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full test suite is blocked locally by Docker/Testcontainers Redis startup failures and one existing admin query assertion failure
* Separate recruitment reason from recruitment type
RecruitType now represents the 모집 유형 axis, so the 모집 사유/회차 성격 needs a separate field before validation and recruitId APIs are introduced. This adds the smallest schema-backed model surface while keeping existing 정규 모집 defaults stable.
Constraint: PR diff should stay near 300 lines and not mix API/service validation changes
Rejected: Include combination validation in this PR | validation is a separate behavior change and review topic
Rejected: Leave RecruitTypeDetail as enum-only | persistence would still lack the field required by later recruitId flows
Confidence: high
Scope-risk: narrow
Directive: Do not start using RecruitTypeDetail for public API semantics until allowed combinations are validated
Tested: ./gradlew test --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full suite, due existing Redis/Testcontainers and AdminApplyQueryRepository failures observed before this change
* Represent supporter applicants in the recruitment base model
Supporter recruiting needs a target job family before recruitId-based APIs arrive. This keeps the change at the enum boundary and avoids mixing member schema work into the current recruitment model PR.
Constraint: Current PR should stay around the recruitment base model and avoid member schema/API changes
Rejected: Add MemberType in the same PR | it introduces member persistence and admin-filter scope
Confidence: high
Scope-risk: narrow
Directive: Do not use JobFamily.MAKERS; makers remains a recruit type whose target job families are PM/PD/FE/BE
Tested: ./gradlew test --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' -x jacocoTestCoverageVerification --rerun-tasks
* Distinguish member type from authorization role
Recruitment expansion needs a member classification that survives after applicants join. This adds the persisted MemberType axis without changing admin APIs yet, so later filters can use member type independently from Role permissions.
Constraint: Keep this PR at model/schema level and avoid admin filter API changes
Rejected: Infer MAKERS during backfill | existing data has no reliable marker for makers membership
Confidence: high
Scope-risk: moderate
Directive: Role remains authorization; do not use Role as the source of truth for member type in new filters
Tested: ./gradlew test --tests 'org.ject.support.domain.member.MemberTypeTest' --tests 'org.ject.support.domain.member.MemberTest' --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' -x jacocoTestCoverageVerification --rerun-tasks
Tested: ./gradlew test --tests 'org.ject.support.domain.member.repository.MemberRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
* Prevent invalid expanded recruitment combinations
Expanded recruitment types need a domain guard before recruitId-based APIs start writing MAKERS or SUPPORTERS postings. The validation lives with RecruitType and is enforced by Recruit persistence callbacks so future creation paths share the same rule.
Constraint: Current public recruit APIs still create legacy regular semester recruits by default.
Constraint: Legacy RecruitType values remain readable until follow-up migration and deprecation work.
Rejected: Add request DTO fields now | this PR is limited to the base model and should not expand API contracts yet.
Rejected: Block legacy RecruitType combinations | existing data can still contain legacy values during the compatibility window.
Confidence: high
Scope-risk: moderate
Directive: Do not tighten legacy RecruitType validation until existing recruit_type values are migrated to SEMESTER plus recruitTypeDetail.
Tested: ./gradlew test --tests 'org.ject.support.domain.member.MemberTypeTest' --tests 'org.ject.support.domain.member.MemberTest' --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.member.repository.MemberRepositoryTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full test suite; previous run is blocked by existing Redis/Testcontainers and admin query test failures.
* Address recruitment typing review gaps
Review feedback exposed two consistency gaps in the expanded recruitment base model: SUPPORTER flags were not initialized after restart and new SUPPORTER members could still default to SEMESTER memberType. The fix makes flag initialization derive from JobFamily values and centralizes role-to-memberType mapping for creation paths.
Constraint: Keep this PR limited to base model and guardrail fixes; public recruit APIs remain unchanged.
Constraint: Existing migration policy maps role=SUPPORTER to member_type=SUPPORTERS, so new creation paths must follow the same rule.
Rejected: Keep AccessPeriodInitializerTest as Redis integration only | local verification remains blocked by Testcontainers and the logic can be covered with a faster unit test.
Rejected: Change V26 backfill for MAKERS/SUPPORTERS | those recruit_type values are introduced by this PR and cannot exist before V26 runs.
Confidence: high
Scope-risk: moderate
Directive: When adding a JobFamily, AccessPeriodInitializer should continue deriving startup flags from JobFamily.values rather than a hand-maintained list.
Tested: ./gradlew test --tests 'org.ject.support.domain.member.MemberTypeTest' --tests 'org.ject.support.domain.member.MemberTest' --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.member.repository.MemberRepositoryTest' --tests 'org.ject.support.admin.member.service.AdminMemberServiceTest' --tests 'org.ject.support.admin.account.service.AdminAccountServiceTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' --tests 'org.ject.support.domain.recruit.service.AccessPeriodInitializerTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full suite; known unrelated Redis/Testcontainers and admin query assertion blockers remain from earlier runs.
* Keep access flag test scoped to supporter coverage
The review fix only needs to prove SUPPORTER recruit flags are initialized. Restoring the existing integration-test shape keeps the PR smaller while still adding the missing SUPPORTER coverage.
Constraint: PRs should stay close to the 300-line review budget where practical.
Rejected: Replace the Redis integration test with a Mockito unit test | it increases churn and changes test coverage shape beyond the review comment.
Confidence: high
Scope-risk: narrow
Tested: ./gradlew test --tests 'org.ject.support.domain.member.MemberTypeTest' --tests 'org.ject.support.domain.member.MemberTest' --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.member.repository.MemberRepositoryTest' --tests 'org.ject.support.admin.member.service.AdminMemberServiceTest' --tests 'org.ject.support.admin.account.service.AdminAccountServiceTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: AccessPeriodInitializerTest locally; Redis Testcontainers remains unavailable in this environment.
* Align new tests with team naming convention
The PR introduced tests using @DisplayName plus English method names. Team convention is to express test intent directly in Korean method names, so the newly added tests now follow that style while existing pre-PR DisplayName usages remain untouched.
Constraint: Only update tests introduced or extended by this PR.
Rejected: Remove every existing @DisplayName in touched files | that would rewrite unrelated legacy tests outside the review feedback scope.
Confidence: high
Scope-risk: narrow
Tested: ./gradlew test --tests 'org.ject.support.domain.member.JobFamilyTest' --tests 'org.ject.support.domain.member.MemberTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTypeTest' --tests 'org.ject.support.domain.recruit.domain.RecruitTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
* Add TODO for migrating recruit_type data
Updated comment to include a TODO note about migrating existing recruit_type data.
* fix:관리자 계정 수정 - 이메일 수정 제외 (#533)
* feat: 활성 모집 공고 목록 API 추가 (#535)
* Expose active recruitment choices for applicants
Applicants need a public entry point that lists currently available postings before the recruitId-based apply flow is introduced. The API returns stable posting identifiers plus type/detail/job-family display metadata, and normalizes legacy recruit types so the new public contract does not leak old enum values.
Constraint: Keep the PR near the 300-line review budget and avoid changing existing apply APIs in this step
Rejected: Reuse /admin/recruits | public applicant discovery should not depend on backoffice routes or permissions
Confidence: high
Scope-risk: narrow
Directive: Do not expose legacy RecruitType values from new public recruitment APIs without an explicit compatibility decision
Tested: ./gradlew test --tests 'org.ject.support.domain.recruit.controller.RecruitmentControllerTest' --tests 'org.ject.support.domain.recruit.service.RecruitServiceTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full suite; local Redis Testcontainers remains unavailable in this environment
Related: #534
* Separate public and admin recruit controllers
The applicant-facing active recruitment endpoint should own the neutral RecruitController name, while existing /admin/recruits behavior remains explicitly marked as admin-only. This keeps URL contracts unchanged and postpones any broader admin API migration.
Constraint: Preserve existing /admin/recruits routes and the new /recruitments/active route
Rejected: Keep RecruitmentController | creates a naming split where the public recruit resource is not represented by RecruitController
Confidence: high
Scope-risk: narrow
Directive: Keep future applicant-facing recruitment APIs under RecruitController unless they are explicitly backoffice-only
Tested: ./gradlew test --tests 'org.ject.support.domain.recruit.controller.RecruitControllerTest' --tests 'org.ject.support.domain.recruit.service.RecruitServiceTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: AdminRecruitControllerTest execution; local Redis Testcontainers remains unavailable, but compileTestJava covered the renamed test and controller
Related: #534
* Align recruit tests with team naming convention
The team prefers descriptive Korean test method names over @DisplayName annotations. The PR now follows that convention for the moved admin recruit tests and the touched recruit repository test.
Constraint: Limit the change to tests touched by the current PR
Rejected: Repo-wide @DisplayName cleanup | unrelated to this PR and would expand review scope
Confidence: high
Scope-risk: narrow
Tested: ./gradlew compileTestJava test --tests 'org.ject.support.domain.recruit.controller.RecruitControllerTest' --tests 'org.ject.support.domain.recruit.service.RecruitServiceTest' --tests 'org.ject.support.domain.recruit.repository.RecruitRepositoryTest' -x jacocoTestCoverageVerification --rerun-tasks
Not-tested: Full suite; local Redis Testcontainers remains unavailable
Related: #534
* feat: 모집 공고 API 리팩토링 (#537)
* Align public recruit path with existing API naming
The active recruit endpoint was introduced under /recruitments, but the current rollout should avoid broad URL vocabulary changes while frontend integration is pending. Keep the endpoint under /recruit and limit this PR to controller/API spec/test path updates.
Constraint: Frontend integration should not absorb URL naming changes yet
Rejected: Rename response field recruitments | expands frontend payload contract changes
Confidence: high
Scope-risk: narrow
Tested: ./gradlew cleanTest test --tests org.ject.support.domain.recruit.controller.RecruitControllerTest -x jacocoTestCoverageVerification
Not-tested: Full test suite; targeted path-only change
Related: #536
* Restore public recruits path for active listings
The previous correction used singular /recruit, but the existing public naming is plural /recruits. Keep the active listing endpoint aligned with that existing route vocabulary instead of introducing another URL shape.
Constraint: Frontend integration should avoid API URL churn
Rejected: Keep /recruit | does not match the existing public route naming
Confidence: high
Scope-risk: narrow
Tested: ./gradlew cleanTest test --tests org.ject.support.domain.recruit.controller.RecruitControllerTest -x jacocoTestCoverageVerification
Not-tested: Full test suite; targeted route correction only
Related: #536
* Allow question lookup by recruit id
Applicants need to continue using the existing /apply/questions URL while the frontend migrates gradually. Extend the current question lookup contract with an optional recruitId query path and keep the legacy jobFamily lookup unchanged.
Constraint: Do not introduce a new questions URL in this rollout
Rejected: Add /recruitments/{recruitId}/questions | creates frontend URL churn before integration capacity is available
Confidence: high
Scope-risk: moderate
Directive: Keep /apply/questions jobFamily compatibility until the recruitId-based apply flow is fully adopted
Tested: ./gradlew cleanTest test --tests org.ject.support.domain.recruit.service.QuestionServiceTest --tests org.ject.support.domain.recruit.repository.QuestionQueryRepositoryTest -x jacocoTestCoverageVerification
Not-tested: QuestionControllerTest locally; blocked by Docker/Testcontainers Redis availability
Related: #536
* Require recruit id for question lookup
The public question lookup contract now identifies the active notice directly, so the controller no longer accepts a parallel jobFamily filter or validates a mixed recruitId/jobFamily condition. The service and query layer follow the same single-key path, which keeps cache entries scoped by recruit id and avoids exposing legacy jobFamily lookup behavior through this API.
Constraint: Review feedback requested recruitId as the required question lookup parameter
Rejected: Keep jobFamily as an optional compatibility parameter | it preserved ambiguity and required extra mismatch handling
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce jobFamily-based question lookup without a separate compatibility decision
Tested: ./gradlew cleanTest test --tests org.ject.support.domain.recruit.service.QuestionServiceTest --tests org.ject.support.domain.recruit.repository.QuestionQueryRepositoryTest -x jacocoTestCoverageVerification
Not-tested: QuestionControllerTest and CacheFallbackIntegrationTest require local Docker/Testcontainers Redis; context load failed before tests ran
* Assert question error response code
Question lookup errors are serialized through ErrorResponse, whose machine-readable value is exposed as code rather than status. Keeping the test on code makes the missing recruitId case verify the actual error contract instead of a success-response field.
Constraint: CodeRabbit identified the stale status-path assertion pattern in the outdated review thread
Confidence: high
Scope-risk: narrow
Tested: ./gradlew cleanTest test --tests org.ject.support.domain.recruit.service.QuestionServiceTest --tests org.ject.support.domain.recruit.repository.QuestionQueryRepositoryTest -x jacocoTestCoverageVerification
Not-tested: QuestionControllerTest requires local Docker/Testcontainers Redis; previous runs failed during context loading before assertions
* Keep wrapped error status assertion
QuestionControllerTest should assert the final API envelope produced by ResponseWrapper. ErrorResponse exposes code internally, but the response advice converts it into ApiResponse.status for clients, so the missing recruitId case must continue to verify status=GLOBAL-10.
Constraint: ResponseWrapper wraps ErrorResponse into ApiResponse before serialization
Rejected: Assert $.code | t…1 parent 99700bc commit dea6e4b
12 files changed
Lines changed: 175 additions & 128 deletions
File tree
- src
- main/java/org/ject/support
- admin/member
- dto/request
- service
- domain
- member
- entity
- repository
- project/repository
- test/java/org/ject/support
- admin/member
- controller
- service
- domain
- member/repository
- project/repository
Lines changed: 11 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | 3 | | |
6 | 4 | | |
7 | 5 | | |
| |||
29 | 27 | | |
30 | 28 | | |
31 | 29 | | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
42 | 41 | | |
43 | 42 | | |
44 | 43 | | |
| |||
Lines changed: 5 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
| 19 | + | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
| 37 | + | |
43 | 38 | | |
44 | 39 | | |
45 | 40 | | |
| |||
Lines changed: 11 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | 5 | | |
7 | | - | |
8 | 6 | | |
9 | 7 | | |
10 | 8 | | |
| |||
35 | 33 | | |
36 | 34 | | |
37 | 35 | | |
38 | | - | |
| 36 | + | |
39 | 37 | | |
40 | 38 | | |
41 | 39 | | |
| |||
52 | 50 | | |
53 | 51 | | |
54 | 52 | | |
55 | | - | |
56 | | - | |
| 53 | + | |
| 54 | + | |
57 | 55 | | |
58 | 56 | | |
59 | 57 | | |
| |||
95 | 93 | | |
96 | 94 | | |
97 | 95 | | |
98 | | - | |
| 96 | + | |
99 | 97 | | |
100 | 98 | | |
101 | 99 | | |
| |||
105 | 103 | | |
106 | 104 | | |
107 | 105 | | |
108 | | - | |
109 | | - | |
110 | | - | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
111 | 109 | | |
112 | 110 | | |
113 | 111 | | |
| |||
116 | 114 | | |
117 | 115 | | |
118 | 116 | | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
| 117 | + | |
| 118 | + | |
124 | 119 | | |
125 | 120 | | |
126 | 121 | | |
127 | 122 | | |
128 | 123 | | |
129 | | - | |
130 | | - | |
| 124 | + | |
| 125 | + | |
131 | 126 | | |
132 | 127 | | |
133 | 128 | | |
| |||
Lines changed: 7 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | | - | |
82 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
83 | 88 | | |
84 | 89 | | |
85 | 90 | | |
86 | 91 | | |
87 | 92 | | |
88 | | - | |
89 | 93 | | |
90 | 94 | | |
91 | 95 | | |
| |||
Lines changed: 30 additions & 34 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| 96 | + | |
96 | 97 | | |
97 | 98 | | |
98 | 99 | | |
| |||
120 | 121 | | |
121 | 122 | | |
122 | 123 | | |
123 | | - | |
| 124 | + | |
124 | 125 | | |
125 | 126 | | |
126 | 127 | | |
127 | 128 | | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
132 | 132 | | |
133 | 133 | | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
138 | 137 | | |
139 | 138 | | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
144 | 142 | | |
145 | 143 | | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
150 | 147 | | |
151 | 148 | | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
156 | 152 | | |
157 | 153 | | |
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
| 45 | + | |
| 46 | + | |
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| |||
Lines changed: 7 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
233 | | - | |
234 | | - | |
| 233 | + | |
| 234 | + | |
235 | 235 | | |
236 | | - | |
237 | | - | |
| 236 | + | |
| 237 | + | |
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
251 | | - | |
| 251 | + | |
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
| |||
258 | 258 | | |
259 | 259 | | |
260 | 260 | | |
261 | | - | |
| 261 | + | |
262 | 262 | | |
263 | 263 | | |
264 | 264 | | |
| |||
267 | 267 | | |
268 | 268 | | |
269 | 269 | | |
270 | | - | |
| 270 | + | |
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
| |||
Lines changed: 7 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
109 | | - | |
| 108 | + | |
| 109 | + | |
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| |||
Lines changed: 14 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
84 | | - | |
| 83 | + | |
| 84 | + | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
88 | | - | |
89 | | - | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
90 | 95 | | |
91 | 96 | | |
92 | 97 | | |
| |||
95 | 100 | | |
96 | 101 | | |
97 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
98 | 107 | | |
99 | 108 | | |
100 | 109 | | |
| |||
0 commit comments