diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml
new file mode 100644
index 0000000000..59bfd7cd4d
--- /dev/null
+++ b/.github/auto_assign.yml
@@ -0,0 +1,12 @@
+addAssignees: author
+numberOfReviewers: 2
+addReviewers: true
+reviewers:
+ - BaeJinho4028
+ - Soundbar91
+ - ImTotem
+ - kih1015
+ - DHkimgit
+ - taejinn
+ - dh2906
+ - JanooGwan
diff --git a/.github/auto_assign_team_business.yml b/.github/auto_assign_team_business.yml
deleted file mode 100644
index f2789c3f3e..0000000000
--- a/.github/auto_assign_team_business.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-addAssignees: author # 작성자를 assignee로 지정
-numberOfReviewers: 0 # 전원 리뷰어로 지정
-addReviewers: true
-reviewers:
- - ImTotem
- - DHkimgit
- - Soundbar91
diff --git a/.github/auto_assign_team_campus.yml b/.github/auto_assign_team_campus.yml
deleted file mode 100644
index 7c4c5eb78e..0000000000
--- a/.github/auto_assign_team_campus.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-addAssignees: author # 작성자를 assignee로 지정
-numberOfReviewers: 0 # 전원 리뷰어로 지정
-addReviewers: true
-reviewers:
- - krSeonghyeon
- - Soundbar91
- - duehee
diff --git a/.github/auto_assign_team_user.yml b/.github/auto_assign_team_user.yml
deleted file mode 100644
index c4ded5e347..0000000000
--- a/.github/auto_assign_team_user.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-addAssignees: author # 작성자를 assignee로 지정
-numberOfReviewers: 0 # 전원 리뷰어로 지정
-addReviewers: true
-reviewers:
- - Choon0414
- - Baejinho4028
- - kih1015
diff --git a/.github/workflows/flyway-dangerous-sql-validator.yml b/.github/workflows/flyway-dangerous-sql-validator.yml
index a784970fb1..c85a0c2862 100644
--- a/.github/workflows/flyway-dangerous-sql-validator.yml
+++ b/.github/workflows/flyway-dangerous-sql-validator.yml
@@ -32,7 +32,7 @@ jobs:
for file in $(git diff --name-only "$BASE" "$HEAD" -- src/main/resources/db/migration/*.sql); do
ADDED_SQL=$(git diff "$BASE" "$HEAD" -- "$file" \
- | grep -i -wE "^\+.*\b(DROP|TRUNCATE|RENAME|CHANGE)\b" || true)
+ | grep -i -wE "^\+.*\b(DROP COLUMN|TRUNCATE|RENAME|CHANGE)\b" || true)
if [[ -n "$ADDED_SQL" ]]; then
echo "::error::⚠️ 위험 SQL 감지됨"
diff --git a/.github/workflows/pr-label-reviewer-assigner.yml b/.github/workflows/pr-label-reviewer-assigner.yml
index f840839042..a8c43c2bd3 100644
--- a/.github/workflows/pr-label-reviewer-assigner.yml
+++ b/.github/workflows/pr-label-reviewer-assigner.yml
@@ -2,7 +2,7 @@ name: "PR Label & Assign Reviewers"
on:
pull_request:
- types: [opened, labeled]
+ types: [opened, labeled, ready_for_review]
jobs:
label_and_assign:
@@ -20,38 +20,10 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # 3. 최신 PR 라벨 목록 조회
- - name: Fetch current PR labels
- id: get_labels
- uses: actions/github-script@v6
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- script: |
- const { data: labels } = await github.rest.issues.listLabelsOnIssue({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.payload.pull_request.number
- });
- return labels.map(l => l.name);
-
- # 4. 라벨별 리뷰어 할당
- - name: Assign Team Business
- if: contains(steps.get_labels.outputs.result, 'Team Business')
- uses: kentaro-m/auto-assign-action@v2.0.0
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- configuration-path: .github/auto_assign_team_business.yml
-
- - name: Assign Team Campus
- if: contains(steps.get_labels.outputs.result, 'Team Campus')
- uses: kentaro-m/auto-assign-action@v2.0.0
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- configuration-path: .github/auto_assign_team_campus.yml
-
- - name: Assign Team User
- if: contains(steps.get_labels.outputs.result, 'Team User')
+ # 3. Team Members에서 랜덤 2명 리뷰어 할당 (Draft 제외)
+ - name: Assign Random Reviewers
+ if: github.event.pull_request.draft == false
uses: kentaro-m/auto-assign-action@v2.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- configuration-path: .github/auto_assign_team_user.yml
+ configuration-path: .github/auto_assign.yml
diff --git a/.github/workflows/pr-reviewers-assigner.yml b/.github/workflows/pr-reviewers-assigner.yml
deleted file mode 100644
index ac88e8f14b..0000000000
--- a/.github/workflows/pr-reviewers-assigner.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Assign Reviewers by Label
-on:
- pull_request:
- types: [opened, labeled, unlabeled]
-
-jobs:
- assign:
- runs-on: ubuntu-latest
- steps:
- - name: Check if Team Business
- if: contains(toJson(github.event.pull_request.labels), 'Team Business')
- uses: kentaro-m/auto-assign-action@v2.0.0
- with:
- configuration-path: .github/auto_assign_team_business.yml
-
- - name: Check if Team Campus
- if: contains(toJson(github.event.pull_request.labels), 'Team Campus')
- uses: kentaro-m/auto-assign-action@v2.0.0
- with:
- configuration-path: .github/auto_assign_team_campus.yml
-
- - name: Check if Team User
- if: contains(toJson(github.event.pull_request.labels), 'Team User')
- uses: kentaro-m/auto-assign-action@v2.0.0
- with:
- configuration-path: .github/auto_assign_team_user.yml
diff --git a/README.md b/README.md
index e7e45dc050..34f094c494 100644
--- a/README.md
+++ b/README.md
@@ -97,19 +97,40 @@ src
---
-### 🧑🧑🧒🧒 Team Members
+
+🧑🧑🧒🧒 Team Members
+
+
+
+#### Active Members
+
+|
|
|
|
+| :--: | :--: | :--: |
+| [관규](https://github.com/Soundbar91) | [동훈](https://github.com/dh2906) | [두현](https://github.com/DHkimgit) |
-|
|
|
|
|
+|
|
|
|
+| :--: | :--: | :--: |
+| [성빈](https://github.com/ImTotem) | [진호](https://github.com/BaeJinho4028) | [태진](https://github.com/taejinn) |
+
+#### Former Members
+
+|
|
|
|
|
| :--: | :--: | :--: | :--: |
-| [진호](https://github.com/BaeJinho4028) | [성현](https://github.com/krSeonghyeon) | [관규](https://github.com/Soundbar91) | [성빈](https://github.com/ImTotem) |
+| [다희](https://github.com/daheeParkk) | [선권](https://github.com/songsunkook) | [성재](https://github.com/seongjae6751) | [성현](https://github.com/krSeonghyeon) |
-|
|
|
|
|
+|
|
|
|
|
| :--: | :--: | :--: | :--: |
-| [정빈](https://github.com/duehee) | [현식](https://github.com/Choon0414) | [인화](https://github.com/kih1015) | [두현](https://github.com/DHkimgit) |
+| [원경](https://github.com/kwoo28) | [인화](https://github.com/kih1015) | [정빈](https://github.com/duehee) | [준기](https://github.com/dradnats1012) |
-|
|
|
|
|
+|
|
|
|
|
| :--: | :--: | :--: | :--: |
-| [박종범](https://github.com/asa9874) | [박태진](https://github.com/taejinn) | [이동훈](https://github.com/dh2906) | [임아리](https://github.com/dldb-chamchi) |
+| [준영](https://github.com/johnny19991006) | [준호](https://github.com/Choi-JJunho) | [한수](https://github.com/Invidam) | [현수](https://github.com/20HyeonsuLee) |
+
+|
|
+| :--: |
+| [현식](https://github.com/Choon0414) |
+
+
---
diff --git a/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordApi.java b/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordApi.java
index cf3d4e2cab..b39076ed6b 100644
--- a/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordApi.java
+++ b/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordApi.java
@@ -7,10 +7,12 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
import in.koreatech.koin.admin.keyword.dto.AdminFilteredKeywordsResponse;
import in.koreatech.koin.admin.keyword.dto.AdminKeywordFilterRequest;
+import in.koreatech.koin.domain.community.keyword.enums.KeywordCategory;
import in.koreatech.koin.global.auth.Auth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
@@ -36,6 +38,7 @@ public interface AdminKeywordApi {
@AdminActivityLogging(domain = KEYWORDS)
ResponseEntity toggleKeywordFilter(
@Valid @RequestBody AdminKeywordFilterRequest request,
+ @RequestParam(value = "type", required = false, defaultValue = "KOREATECH") KeywordCategory keywordCategory,
@Auth(permit = {ADMIN}) Integer adminId
);
@@ -50,6 +53,7 @@ ResponseEntity toggleKeywordFilter(
@Operation(summary = "필터링 된 키워드 조회")
@GetMapping("/admin/articles/keyword/filtered")
ResponseEntity getFilteredKeywords(
+ @RequestParam(value = "type", required = false, defaultValue = "KOREATECH") KeywordCategory keywordCategory,
@Auth(permit = {ADMIN}) Integer adminId
);
}
diff --git a/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordController.java b/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordController.java
index 836097621a..0fb3a377e4 100644
--- a/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordController.java
+++ b/src/main/java/in/koreatech/koin/admin/keyword/controller/AdminKeywordController.java
@@ -8,12 +8,14 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
import in.koreatech.koin.admin.keyword.dto.AdminFilteredKeywordsResponse;
import in.koreatech.koin.admin.keyword.dto.AdminKeywordFilterRequest;
import in.koreatech.koin.admin.keyword.service.AdminKeywordService;
+import in.koreatech.koin.domain.community.keyword.enums.KeywordCategory;
import in.koreatech.koin.global.auth.Auth;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@@ -29,17 +31,19 @@ public class AdminKeywordController implements AdminKeywordApi {
@AdminActivityLogging(domain = KEYWORDS)
public ResponseEntity toggleKeywordFilter(
@Valid @RequestBody AdminKeywordFilterRequest request,
+ @RequestParam(value = "type", required = false, defaultValue = "KOREATECH") KeywordCategory keywordCategory,
@Auth(permit = {ADMIN}) Integer adminId
) {
- adminKeywordService.filterKeyword(request.keyword(), request.isFiltered());
+ adminKeywordService.filterKeyword(request.keyword(), request.isFiltered(), keywordCategory);
return ResponseEntity.ok().build();
}
@GetMapping("/filtered")
public ResponseEntity getFilteredKeywords(
+ @RequestParam(value = "type", required = false, defaultValue = "KOREATECH") KeywordCategory keywordCategory,
@Auth(permit = {ADMIN}) Integer adminId
) {
- AdminFilteredKeywordsResponse response = adminKeywordService.getFilteredKeywords();
+ AdminFilteredKeywordsResponse response = adminKeywordService.getFilteredKeywords(keywordCategory);
return ResponseEntity.ok(response);
}
}
diff --git a/src/main/java/in/koreatech/koin/admin/keyword/repository/AdminArticleKeywordRepository.java b/src/main/java/in/koreatech/koin/admin/keyword/repository/AdminArticleKeywordRepository.java
index cf64af684e..993013447e 100644
--- a/src/main/java/in/koreatech/koin/admin/keyword/repository/AdminArticleKeywordRepository.java
+++ b/src/main/java/in/koreatech/koin/admin/keyword/repository/AdminArticleKeywordRepository.java
@@ -6,16 +6,19 @@
import org.springframework.data.repository.Repository;
import in.koreatech.koin.domain.community.keyword.exception.ArticleKeywordNotFoundException;
+import in.koreatech.koin.domain.community.keyword.enums.KeywordCategory;
import in.koreatech.koin.domain.community.keyword.model.ArticleKeyword;
public interface AdminArticleKeywordRepository extends Repository {
- Optional findByKeyword(String keyword);
+ Optional findByKeywordAndCategory(String keyword, KeywordCategory category);
- default ArticleKeyword getByKeyword(String keyword) {
- return findByKeyword(keyword)
- .orElseThrow(() -> ArticleKeywordNotFoundException.withDetail("keyword : " + keyword));
+ default ArticleKeyword getByKeywordAndCategory(String keyword, KeywordCategory category) {
+ return findByKeywordAndCategory(keyword, category)
+ .orElseThrow(() -> ArticleKeywordNotFoundException.withDetail(
+ "keyword : " + keyword + ", category : " + category
+ ));
}
- List findByIsFiltered(boolean isFiltered);
+ List findByIsFilteredAndCategory(boolean isFiltered, KeywordCategory category);
}
diff --git a/src/main/java/in/koreatech/koin/admin/keyword/service/AdminKeywordService.java b/src/main/java/in/koreatech/koin/admin/keyword/service/AdminKeywordService.java
index 6ad1dac487..96a428d1f2 100644
--- a/src/main/java/in/koreatech/koin/admin/keyword/service/AdminKeywordService.java
+++ b/src/main/java/in/koreatech/koin/admin/keyword/service/AdminKeywordService.java
@@ -8,6 +8,7 @@
import in.koreatech.koin.admin.keyword.repository.AdminArticleKeywordRepository;
import in.koreatech.koin.admin.keyword.dto.AdminFilteredKeywordsResponse;
+import in.koreatech.koin.domain.community.keyword.enums.KeywordCategory;
import in.koreatech.koin.domain.community.keyword.model.ArticleKeyword;
import in.koreatech.koin.global.exception.custom.KoinIllegalArgumentException;
import lombok.RequiredArgsConstructor;
@@ -20,19 +21,22 @@ public class AdminKeywordService {
private final AdminArticleKeywordRepository adminArticleKeywordRepository;
@Transactional
- public void filterKeyword(String keyword, Boolean isFiltered) {
- ArticleKeyword articleKeyword = adminArticleKeywordRepository.getByKeyword(keyword);
+ public void filterKeyword(String keyword, Boolean isFiltered, KeywordCategory category) {
+ ArticleKeyword articleKeyword = adminArticleKeywordRepository.getByKeywordAndCategory(keyword, category);
if (Objects.equals(articleKeyword.getIsFiltered(), isFiltered)) {
String action = isFiltered ? "필터링 된" : "필터링이 취소된";
- throw new KoinIllegalArgumentException("이미 " + action + " 키워드입니다: " + keyword);
+ throw new KoinIllegalArgumentException("이미 " + action + " 키워드입니다: " + keyword + ", category: " + category);
}
articleKeyword.applyFiltered(isFiltered);
}
- public AdminFilteredKeywordsResponse getFilteredKeywords() {
- List filteredKeywords = adminArticleKeywordRepository.findByIsFiltered(true);
+ public AdminFilteredKeywordsResponse getFilteredKeywords(KeywordCategory category) {
+ List filteredKeywords = adminArticleKeywordRepository.findByIsFilteredAndCategory(
+ true,
+ category
+ );
return AdminFilteredKeywordsResponse.from(filteredKeywords);
}
}
diff --git a/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberApi.java b/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberApi.java
deleted file mode 100644
index 332f91a0e7..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberApi.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package in.koreatech.koin.admin.member.controller;
-
-import static in.koreatech.koin.admin.history.enums.DomainType.MEMBERS;
-import static in.koreatech.koin.domain.user.model.UserType.ADMIN;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
-import in.koreatech.koin.admin.member.dto.AdminMemberRequest;
-import in.koreatech.koin.admin.member.dto.AdminMemberResponse;
-import in.koreatech.koin.admin.member.dto.AdminMembersResponse;
-import in.koreatech.koin.admin.member.enums.TrackTag;
-import in.koreatech.koin.global.auth.Auth;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.validation.Valid;
-
-@Tag(name = "(Admin) AdminMember: BCSDLab 회원", description = "관리자 권한으로 BCSDLab 회원 정보를 관리한다")
-public interface AdminMemberApi {
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "페이지별 BCSDLab 회원 리스트 조회")
- @SecurityRequirement(name = "Jwt Authentication")
- @GetMapping("/admin/members")
- ResponseEntity getMembers(
- @RequestParam(name = "page", defaultValue = "1") Integer page,
- @RequestParam(name = "limit", defaultValue = "50", required = false) Integer limit,
- @RequestParam(name = "track") TrackTag track,
- @RequestParam(name = "is_deleted", defaultValue = "false") Boolean isDeleted,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "201"),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "BCSDLab 회원 생성")
- @SecurityRequirement(name = "Jwt Authentication")
- @PostMapping("/admin/members")
- @AdminActivityLogging(domain = MEMBERS)
- ResponseEntity createMember(
- @RequestBody @Valid AdminMemberRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "BCSDLab 회원 조회")
- @SecurityRequirement(name = "Jwt Authentication")
- @GetMapping("/admin/members/{id}")
- ResponseEntity getMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "BCSDLab 회원 삭제")
- @SecurityRequirement(name = "Jwt Authentication")
- @DeleteMapping("/admin/members/{id}")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- ResponseEntity deleteMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "BCSDLab 회원 수정")
- @SecurityRequirement(name = "Jwt Authentication")
- @PutMapping("/admin/members/{id}")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- ResponseEntity updateMember(
- @PathVariable("id") Integer memberId,
- @RequestBody @Valid AdminMemberRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "BCSDLab 회원 삭제 취소")
- @SecurityRequirement(name = "Jwt Authentication")
- @PostMapping("/admin/members/{id}/undelete")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- ResponseEntity undeleteMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberController.java b/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberController.java
deleted file mode 100644
index b715d7eee5..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/controller/AdminMemberController.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package in.koreatech.koin.admin.member.controller;
-
-import static in.koreatech.koin.admin.history.enums.DomainType.MEMBERS;
-import static in.koreatech.koin.domain.user.model.UserType.ADMIN;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
-import in.koreatech.koin.admin.member.dto.AdminMemberRequest;
-import in.koreatech.koin.admin.member.dto.AdminMemberResponse;
-import in.koreatech.koin.admin.member.dto.AdminMembersResponse;
-import in.koreatech.koin.admin.member.enums.TrackTag;
-import in.koreatech.koin.admin.member.service.AdminMemberService;
-import in.koreatech.koin.global.auth.Auth;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-
-@RestController
-@RequiredArgsConstructor
-public class AdminMemberController implements AdminMemberApi {
-
- private final AdminMemberService adminMemberService;
-
- @GetMapping("/admin/members")
- public ResponseEntity getMembers(
- @RequestParam(name = "page", defaultValue = "1") Integer page,
- @RequestParam(name = "limit", defaultValue = "50", required = false) Integer limit,
- @RequestParam(name = "track") TrackTag track,
- @RequestParam(name = "is_deleted", defaultValue = "false") Boolean isDeleted,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- return ResponseEntity.ok().body(adminMemberService.getMembers(page, limit, track, isDeleted));
- }
-
- @PostMapping("/admin/members")
- @AdminActivityLogging(domain = MEMBERS)
- public ResponseEntity createMember(
- @RequestBody @Valid AdminMemberRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminMemberService.createMember(request);
- return ResponseEntity.status(HttpStatus.CREATED).build();
- }
-
- @GetMapping("/admin/members/{id}")
- public ResponseEntity getMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- return ResponseEntity.ok().body(adminMemberService.getMember(memberId));
- }
-
- @DeleteMapping("/admin/members/{id}")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- public ResponseEntity deleteMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminMemberService.deleteMember(memberId);
- return ResponseEntity.ok().build();
- }
-
- @PutMapping("/admin/members/{id}")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- public ResponseEntity updateMember(
- @PathVariable("id") Integer memberId,
- @RequestBody @Valid AdminMemberRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminMemberService.updateMember(memberId, request);
- return ResponseEntity.ok().build();
- }
-
- @PostMapping("/admin/members/{id}/undelete")
- @AdminActivityLogging(domain = MEMBERS, domainIdParam = "memberId")
- public ResponseEntity undeleteMember(
- @PathVariable("id") Integer memberId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminMemberService.undeleteMember(memberId);
- return ResponseEntity.ok().build();
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackApi.java b/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackApi.java
deleted file mode 100644
index 94101dfdea..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackApi.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package in.koreatech.koin.admin.member.controller;
-
-import static in.koreatech.koin.admin.history.enums.DomainType.TECHSTACKS;
-import static in.koreatech.koin.admin.history.enums.DomainType.TRACKS;
-import static in.koreatech.koin.domain.user.model.UserType.ADMIN;
-
-import java.util.List;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
-import in.koreatech.koin.admin.member.dto.AdminTechStackRequest;
-import in.koreatech.koin.admin.member.dto.AdminTechStackResponse;
-import in.koreatech.koin.admin.member.dto.AdminTrackRequest;
-import in.koreatech.koin.admin.member.dto.AdminTrackResponse;
-import in.koreatech.koin.admin.member.dto.AdminTrackSingleResponse;
-import in.koreatech.koin.global.auth.Auth;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.validation.Valid;
-
-@Tag(name = "(Admin) Track: BCSDLab 트랙", description = "관리자 권한으로 BCSDLab 트랙 정보를 관리한다")
-public interface AdminTrackApi {
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "트랙 목록 조회")
- @SecurityRequirement(name = "Jwt Authentication")
- @GetMapping("/admin/tracks")
- ResponseEntity> getTracks(
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "409", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "트랙 생성")
- @SecurityRequirement(name = "Jwt Authentication")
- @PostMapping("/admin/tracks")
- @AdminActivityLogging(domain = TRACKS)
- ResponseEntity createTrack(
- @RequestBody @Valid AdminTrackRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "트랙 단건 조회")
- @SecurityRequirement(name = "Jwt Authentication")
- @GetMapping("/admin/tracks/{id}")
- ResponseEntity getTrack(
- @PathVariable("id") Integer trackId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "409", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "트랙 수정")
- @SecurityRequirement(name = "Jwt Authentication")
- @PutMapping("/admin/tracks/{id}")
- @AdminActivityLogging(domain = TRACKS, domainIdParam = "trackId")
- ResponseEntity updateTrack(
- @PathVariable("id") Integer trackId,
- @RequestBody @Valid AdminTrackRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "204", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "트랙 삭제")
- @SecurityRequirement(name = "Jwt Authentication")
- @DeleteMapping("/admin/tracks/{id}")
- @AdminActivityLogging(domain = TRACKS, domainIdParam = "trackId")
- ResponseEntity deleteTrack(
- @PathVariable("id") Integer trackId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "기술스택 생성")
- @SecurityRequirement(name = "Jwt Authentication")
- @PostMapping("/admin/techStacks")
- @AdminActivityLogging(domain = TECHSTACKS)
- ResponseEntity createTechStack(
- @RequestBody @Valid AdminTechStackRequest request,
- @RequestParam(value = "trackName") String trackName,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "기술스택 수정")
- @SecurityRequirement(name = "Jwt Authentication")
- @PutMapping("/admin/techStacks/{id}")
- @AdminActivityLogging(domain = TECHSTACKS, domainIdParam = "techStackId")
- ResponseEntity updateTechStack(
- @RequestBody @Valid AdminTechStackRequest request,
- @RequestParam(value = "trackName") String trackName,
- @PathVariable("id") Integer techStackId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-
- @ApiResponses(
- value = {
- @ApiResponse(responseCode = "200"),
- @ApiResponse(responseCode = "204", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))),
- @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))),
- }
- )
- @Operation(summary = "기술스택 삭제")
- @SecurityRequirement(name = "Jwt Authentication")
- @DeleteMapping("/admin/techStacks/{id}")
- @AdminActivityLogging(domain = TECHSTACKS, domainIdParam = "techStackId")
- ResponseEntity deleteTechStack(
- @PathVariable("id") Integer techStackId,
- @Auth(permit = {ADMIN}) Integer adminId
- );
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackController.java b/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackController.java
deleted file mode 100644
index fb3324a319..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/controller/AdminTrackController.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package in.koreatech.koin.admin.member.controller;
-
-import static in.koreatech.koin.admin.history.enums.DomainType.TECHSTACKS;
-import static in.koreatech.koin.admin.history.enums.DomainType.TRACKS;
-import static in.koreatech.koin.domain.user.model.UserType.ADMIN;
-
-import java.util.List;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import in.koreatech.koin.admin.history.aop.AdminActivityLogging;
-import in.koreatech.koin.admin.member.dto.AdminTechStackRequest;
-import in.koreatech.koin.admin.member.dto.AdminTechStackResponse;
-import in.koreatech.koin.admin.member.dto.AdminTrackRequest;
-import in.koreatech.koin.admin.member.dto.AdminTrackResponse;
-import in.koreatech.koin.admin.member.dto.AdminTrackSingleResponse;
-import in.koreatech.koin.admin.member.service.AdminTrackService;
-import in.koreatech.koin.global.auth.Auth;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-
-@RestController
-@RequiredArgsConstructor
-public class AdminTrackController implements AdminTrackApi {
-
- private final AdminTrackService adminTrackService;
-
- @GetMapping("/admin/tracks")
- public ResponseEntity> getTracks(
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.getTracks();
- return ResponseEntity.ok(response);
- }
-
- @PostMapping("/admin/tracks")
- @AdminActivityLogging(domain = TRACKS)
- public ResponseEntity createTrack(
- @RequestBody @Valid AdminTrackRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.createTrack(request);
- return ResponseEntity.ok(response);
- }
-
- @GetMapping("/admin/tracks/{id}")
- public ResponseEntity getTrack(
- @PathVariable("id") Integer trackId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.getTrack(trackId);
- return ResponseEntity.ok(response);
- }
-
- @PutMapping("/admin/tracks/{id}")
- @AdminActivityLogging(domain = TRACKS, domainIdParam = "trackId")
- public ResponseEntity updateTrack(
- @PathVariable("id") Integer trackId,
- @RequestBody @Valid AdminTrackRequest request,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.updateTrack(trackId, request);
- return ResponseEntity.ok(response);
- }
-
- @DeleteMapping("/admin/tracks/{id}")
- @AdminActivityLogging(domain = TRACKS, domainIdParam = "trackId")
- public ResponseEntity deleteTrack(
- @PathVariable("id") Integer trackId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminTrackService.deleteTrack(trackId);
- return ResponseEntity.ok().build();
- }
-
- @PostMapping("/admin/techStacks")
- @AdminActivityLogging(domain = TECHSTACKS)
- public ResponseEntity createTechStack(
- @RequestBody @Valid AdminTechStackRequest request,
- @RequestParam String trackName,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.createTechStack(request, trackName);
- return ResponseEntity.ok(response);
- }
-
- @PutMapping("/admin/techStacks/{id}")
- @AdminActivityLogging(domain = TECHSTACKS, domainIdParam = "techStackId")
- public ResponseEntity updateTechStack(
- @RequestBody @Valid AdminTechStackRequest request,
- @RequestParam String trackName,
- @PathVariable("id") Integer techStackId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- var response = adminTrackService.updateTechStack(request, trackName, techStackId);
- return ResponseEntity.ok(response);
- }
-
- @DeleteMapping("/admin/techStacks/{id}")
- @AdminActivityLogging(domain = TECHSTACKS, domainIdParam = "techStackId")
- public ResponseEntity deleteTechStack(
- @PathVariable("id") Integer techStackId,
- @Auth(permit = {ADMIN}) Integer adminId
- ) {
- adminTrackService.deleteTechStack(techStackId);
- return ResponseEntity.ok().build();
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberRequest.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberRequest.java
deleted file mode 100644
index 015a9aa0b4..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberRequest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Member;
-import in.koreatech.koin.domain.member.model.Track;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Pattern;
-import jakarta.validation.constraints.Size;
-
-@JsonNaming(value = SnakeCaseStrategy.class)
-public record AdminMemberRequest(
- @NotNull(message = "이름은 필수입니다.")
- @Size(max = 50, message = "이름의 길이는 최대 50자입니다.")
- @Schema(description = "이름", example = "김주원", requiredMode = REQUIRED)
- String name,
-
- @Size(max = 10, message = "학번의 길이는 최대 10자입니다.")
- @Schema(description = "소속 트랙", example = "2019136037")
- String studentNumber,
-
- @NotNull(message = "트랙은 필수입니다.")
- @Pattern(regexp = "^(Android|BackEnd|FrontEnd|Game|UI\\/UX|HR|iOS|P&M)$", message = "트랙의 형식이 올바르지 않습니다.")
- @Schema(description = "고유 id", example = "BackEnd", requiredMode = REQUIRED)
- String track,
-
- @NotNull(message = "직급은 필수입니다.")
- @Pattern(regexp = "^(Mentor|Regular)$", message = "직급의 형식이 올바르지 않습니다.")
- @Schema(description = "직급", example = "Regular", requiredMode = REQUIRED)
- String position,
-
- @Email(message = "이메일의 길이는 최대 100자입니다.")
- @Schema(description = "이메일", example = "damiano102777@naver.com")
- String email,
-
- @Size(max = 65535, message = "이미지 링크의 길이는 최대 65535자입니다.")
- @Schema(description = "이미지 링크", example = "https://example.com")
- String imageUrl
-) {
- public Member toMember(Track track) {
- return Member.builder()
- .name(name)
- .studentNumber(studentNumber)
- .track(track)
- .position(position)
- .email(email)
- .imageUrl(imageUrl)
- .build();
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberResponse.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberResponse.java
deleted file mode 100644
index b73a371acf..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMemberResponse.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.*;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Member;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@JsonNaming(value = SnakeCaseStrategy.class)
-public record AdminMemberResponse(
- @Schema(description = "고유 id", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "이름", example = "김주원", requiredMode = REQUIRED)
- String name,
-
- @Schema(description = "학번", example = "2019136037")
- String studentNumber,
-
- @Schema(description = "트랙 이름", example = "BackEnd", requiredMode = REQUIRED)
- String track,
-
- @Schema(description = "직책", example = "Regular", requiredMode = REQUIRED)
- String position,
-
- @Schema(description = "이메일", example = "damiano102777@naver.com")
- String email,
-
- @Schema(description = "이미지 url", example = "https://static.koreatech.in/test.png")
- String imageUrl,
-
- @Schema(description = "삭제(soft delete) 여부", example = "false", requiredMode = REQUIRED)
- boolean isDeleted
-) {
- public static AdminMemberResponse from(Member member) {
- return new AdminMemberResponse(
- member.getId(),
- member.getName(),
- member.getStudentNumber(),
- member.getTrack() != null ? member.getTrack().getName() : null,
- member.getPosition(),
- member.getEmail(),
- member.getImageUrl(),
- member.isDeleted()
- );
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMembersResponse.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminMembersResponse.java
deleted file mode 100644
index 8fd942268b..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminMembersResponse.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.*;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.springframework.data.domain.Page;
-
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Member;
-import in.koreatech.koin.common.model.Criteria;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@JsonNaming(value = SnakeCaseStrategy.class)
-public record AdminMembersResponse(
- @Schema(description = "조건에 해당하는 총 회원의 수", example = "57", requiredMode = REQUIRED)
- Long totalCount,
-
- @Schema(description = "조건에 해당하는 회원 중에 현재 페이지에서 조회된 수", example = "10", requiredMode = REQUIRED)
- Integer currentCount,
-
- @Schema(description = "조건에 해당하는 회원들을 조회할 수 있는 최대 페이지", example = "6", requiredMode = REQUIRED)
- Integer totalPage,
-
- @Schema(description = "현재 페이지", example = "2", requiredMode = REQUIRED)
- Integer currentPage,
-
- @Schema(description = "회원 정보 리스트", requiredMode = REQUIRED)
- List members
-) {
- public static AdminMembersResponse of(Page pagedResult, Criteria criteria) {
- return new AdminMembersResponse(
- pagedResult.getTotalElements(),
- pagedResult.getContent().size(),
- pagedResult.getTotalPages(),
- criteria.getPage() + 1,
- pagedResult.getContent()
- .stream()
- .map(SimpleMemberInformation::from)
- .collect(Collectors.toList())
- );
- }
- @JsonNaming(value = SnakeCaseStrategy.class)
- private record SimpleMemberInformation(
- @Schema(description = "고유 id", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "이름", example = "김주원", requiredMode = REQUIRED)
- String name,
-
- @Schema(description = "학번", example = "2019136037")
- String studentNumber,
-
- @Schema(description = "트랙 이름", example = "BackEnd", requiredMode = REQUIRED)
- String track,
-
- @Schema(description = "직책", example = "Regular", requiredMode = REQUIRED)
- String position,
-
- @Schema(description = "이메일", example = "damiano102777@naver.com")
- String email,
-
- @Schema(description = "이미지 url", example = "https://static.koreatech.in/test.png")
- String imageUrl,
-
- @Schema(description = "삭제(soft delete) 여부", example = "false", requiredMode = REQUIRED)
- boolean isDeleted
- ) {
-
- public static SimpleMemberInformation from(Member member) {
- return new SimpleMemberInformation(
- member.getId(),
- member.getName(),
- member.getStudentNumber(),
- member.getTrack().getName(),
- member.getPosition(),
- member.getEmail(),
- member.getImageUrl(),
- member.isDeleted()
- );
- }
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackRequest.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackRequest.java
deleted file mode 100644
index 1643ef943e..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackRequest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.TechStack;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
-
-@JsonNaming(SnakeCaseStrategy.class)
-public record AdminTechStackRequest(
- @Schema(description = "이미지 링크", example = "http://url.com")
- String imageUrl,
-
- @Schema(description = "기술 스택명", example = "Spring", requiredMode = REQUIRED)
- @NotBlank(message = "기술 스택명은 비워둘 수 없습니다.")
- String name,
-
- @Schema(description = "기술 스택 설명", example = "스프링은 웹 프레임워크이다")
- String description,
-
- @Schema(description = "삭제 여부", example = "false")
- boolean isDeleted
-) {
-
- public TechStack toEntity(Integer trackId) {
- return TechStack.builder()
- .imageUrl(imageUrl)
- .trackId(trackId)
- .name(name)
- .description(description)
- .isDeleted(isDeleted)
- .build();
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackResponse.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackResponse.java
deleted file mode 100644
index 3562d76354..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTechStackResponse.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import java.time.LocalDateTime;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.TechStack;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@JsonNaming(SnakeCaseStrategy.class)
-public record AdminTechStackResponse(
-
- @Schema(description = "기술스택 고유 ID", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "이미지 링크", example = "http://url.com", requiredMode = REQUIRED)
- String imageUrl,
-
- @Schema(description = "기술 스택명", example = "Spring", requiredMode = REQUIRED)
- String name,
-
- @Schema(description = "기술 스택 설명", example = "스프링은 웹 프레임워크이다", requiredMode = REQUIRED)
- String description,
-
- @Schema(description = "트랙 고유 ID", example = "2", requiredMode = REQUIRED)
- Integer trackId,
-
- @Schema(description = "삭제 여부", example = "false", requiredMode = REQUIRED)
- Boolean isDeleted,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "생성 일자", example = "2024-01-15 12:00:00", requiredMode = REQUIRED)
- LocalDateTime createdAt,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "수정 일자", example = "2024-01-15 12:00:00", requiredMode = REQUIRED)
- LocalDateTime updatedAt
-) {
-
- public static AdminTechStackResponse from(TechStack techStack) {
- return new AdminTechStackResponse(
- techStack.getId(),
- techStack.getImageUrl(),
- techStack.getName(),
- techStack.getDescription(),
- techStack.getTrackId(),
- techStack.isDeleted(),
- techStack.getCreatedAt(),
- techStack.getUpdatedAt()
- );
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackRequest.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackRequest.java
deleted file mode 100644
index cbe9b6e1a0..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackRequest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Track;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-@JsonNaming(SnakeCaseStrategy.class)
-public record AdminTrackRequest(
- @Schema(description = "트랙 명", example = "Backend", requiredMode = REQUIRED)
- @NotBlank(message = "트랙명은 비워둘 수 없습니다.")
- String name,
-
- @Schema(description = "인원 수", example = "15")
- @NotNull(message = "인원 수는 비워둘 수 없습니다.")
- Integer headcount,
-
- @Schema(description = "삭제 여부", example = "false")
- boolean isDeleted
-) {
-
- public Track toEntity() {
- return Track.builder()
- .name(name)
- .headcount(headcount)
- .isDeleted(isDeleted)
- .build();
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackResponse.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackResponse.java
deleted file mode 100644
index db90979c45..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackResponse.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import java.time.LocalDateTime;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Track;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@JsonNaming(SnakeCaseStrategy.class)
-public record AdminTrackResponse(
- @Schema(description = "트랙 고유 ID", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "트랙 명", example = "Backend", requiredMode = REQUIRED)
- String name,
-
- @Schema(description = "인원 수", example = "15", requiredMode = REQUIRED)
- Integer headcount,
-
- @Schema(description = "삭제 여부", example = "false", requiredMode = REQUIRED)
- Boolean isDeleted,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "생성 일자", example = "2023-01-04 12:00:01", requiredMode = REQUIRED)
- LocalDateTime createdAt,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "수정 일자", example = "2023-01-04 12:00:01", requiredMode = REQUIRED)
- LocalDateTime updatedAt
-) {
-
- public static AdminTrackResponse from(Track track) {
- return new AdminTrackResponse(
- track.getId(),
- track.getName(),
- track.getHeadcount(),
- track.isDeleted(),
- track.getCreatedAt(),
- track.getUpdatedAt()
- );
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackSingleResponse.java b/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackSingleResponse.java
deleted file mode 100644
index 13329280e6..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/dto/AdminTrackSingleResponse.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package in.koreatech.koin.admin.member.dto;
-
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED;
-import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonNaming;
-
-import in.koreatech.koin.domain.member.model.Member;
-import in.koreatech.koin.domain.member.model.TechStack;
-import in.koreatech.koin.domain.member.model.Track;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@JsonNaming(SnakeCaseStrategy.class)
-public record AdminTrackSingleResponse(
- @JsonProperty("TrackName")
- @Schema(description = "트랙 명", example = "Backend", requiredMode = REQUIRED)
- String trackName,
-
- @JsonProperty("Members")
- List innerMemberResponses,
-
- @JsonProperty("TechStacks")
- List innerTechStackResponses
-) {
-
- public static AdminTrackSingleResponse of(Track track, List members, List techStacks) {
- return new AdminTrackSingleResponse(
- track.getName(),
- members.stream()
- .map(member -> InnerMemberResponse.from(member, track.getName()))
- .toList(),
- techStacks.stream()
- .map(InnerTechStackResponse::from)
- .toList()
- );
- }
-
- @JsonNaming(value = SnakeCaseStrategy.class)
- private record InnerMemberResponse(
- @Schema(description = "BCSD 회원 고유 ID", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "이름", example = "최준호", requiredMode = REQUIRED)
- String name,
-
- @Schema(description = "학번", example = "2019136135", requiredMode = NOT_REQUIRED)
- String studentNumber,
-
- @Schema(description = "동아리 포지션 `Beginner`, `Regular`, `Mentor`", example = "Regular", requiredMode = REQUIRED)
- String position,
-
- @Schema(description = "트랙 명", example = "Backend", requiredMode = REQUIRED)
- String track,
-
- @Schema(description = "이메일", example = "koin123@koreatech.ac.kr", requiredMode = NOT_REQUIRED)
- String email,
-
- @Schema(description = "이미지 Url", example = "https://static.koreatech.in/example/image.png", requiredMode = NOT_REQUIRED)
- String imageUrl,
-
- @Schema(description = "삭제 여부", example = "false", requiredMode = REQUIRED)
- Boolean isDeleted,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "생성 일자", example = "2023-01-04 12:00:01", requiredMode = REQUIRED)
- LocalDateTime createdAt,
-
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- @Schema(description = "수정 일자", example = "2023-01-04 12:00:01", requiredMode = REQUIRED)
- LocalDateTime updatedAt
- ) {
-
- public static InnerMemberResponse from(Member member, String trackName) {
- return new InnerMemberResponse(
- member.getId(),
- member.getName(),
- member.getStudentNumber(),
- member.getPosition(),
- trackName,
- member.getEmail(),
- member.getImageUrl(),
- member.isDeleted(),
- member.getCreatedAt(),
- member.getUpdatedAt()
- );
- }
- }
-
- @JsonNaming(value = SnakeCaseStrategy.class)
- private record InnerTechStackResponse(
- @Schema(description = "기술 스택 고유 ID", example = "1", requiredMode = REQUIRED)
- Integer id,
-
- @Schema(description = "기술 이름", example = "Backend")
- String name,
-
- @Schema(description = "기술 설명", example = "15")
- String description,
-
- @Schema(description = "이미지 Url", example = "https://static.koreatech.in/example/image.png")
- String imageUrl,
-
- @Schema(description = "트랙 ID", example = "1")
- Integer trackId,
-
- @Schema(description = "삭제 여부", example = "false")
- Boolean isDeleted,
-
- @Schema(description = "생성 일자", example = "2023-01-04 12:00:01")
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createdAt,
-
- @Schema(description = "수정 일자", example = "2023-01-04 12:00:01")
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updatedAt
- ) {
-
- public static InnerTechStackResponse from(TechStack techStack) {
- return new InnerTechStackResponse(
- techStack.getId(),
- techStack.getName(),
- techStack.getDescription(),
- techStack.getImageUrl(),
- techStack.getTrackId(),
- techStack.isDeleted(),
- techStack.getCreatedAt(),
- techStack.getUpdatedAt()
- );
- }
- }
-}
-
diff --git a/src/main/java/in/koreatech/koin/admin/member/enums/TrackTag.java b/src/main/java/in/koreatech/koin/admin/member/enums/TrackTag.java
deleted file mode 100644
index 62324c16c5..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/enums/TrackTag.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package in.koreatech.koin.admin.member.enums;
-
-import lombok.Getter;
-
-@Getter
-public enum TrackTag {
- ANDROID("Android"),
- BACKEND("BackEnd"),
- FRONTEND("FrontEnd"),
- GAME("Game"),
- PM("P&M"),
- HR("HR"),
- UI_UX("UI/UX"),
- IOS("iOS"),
- ;
-
- private final String tag;
-
- TrackTag(String tag) {
- this.tag = tag;
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/exception/TechStackNotFoundException.java b/src/main/java/in/koreatech/koin/admin/member/exception/TechStackNotFoundException.java
deleted file mode 100644
index a9856c6dfe..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/exception/TechStackNotFoundException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package in.koreatech.koin.admin.member.exception;
-
-import in.koreatech.koin.global.exception.custom.DataNotFoundException;
-
-public class TechStackNotFoundException extends DataNotFoundException {
-
- private static final String DEFAULT_MESSAGE = "존재하지 않는 기술스택입니다.";
-
- protected TechStackNotFoundException(String message) {
- super(message);
- }
-
- protected TechStackNotFoundException(String message, String detail) {
- super(message, detail);
- }
-
- public static TechStackNotFoundException withDetail(String detail) {
- return new TechStackNotFoundException(DEFAULT_MESSAGE, detail);
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/exception/TrackNameDuplicationException.java b/src/main/java/in/koreatech/koin/admin/member/exception/TrackNameDuplicationException.java
deleted file mode 100644
index d47d2e49d6..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/exception/TrackNameDuplicationException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package in.koreatech.koin.admin.member.exception;
-
-import in.koreatech.koin.global.exception.custom.DuplicationException;
-
-public class TrackNameDuplicationException extends DuplicationException {
-
- private static final String DEFAULT_MESSAGE = "트랙명이 이미 존재합니다";
-
- protected TrackNameDuplicationException(String message) {
- super(message);
- }
-
- protected TrackNameDuplicationException(String message, String detail) {
- super(message, detail);
- }
-
- public static TrackNameDuplicationException withDetail(String name) {
- return new TrackNameDuplicationException(DEFAULT_MESSAGE, "name: " + name);
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/repository/AdminMemberRepository.java b/src/main/java/in/koreatech/koin/admin/member/repository/AdminMemberRepository.java
deleted file mode 100644
index 4bd51b56fa..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/repository/AdminMemberRepository.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package in.koreatech.koin.admin.member.repository;
-
-import java.util.List;
-import java.util.Optional;
-
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.EntityGraph;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.Repository;
-
-import in.koreatech.koin.domain.member.exception.MemberNotFoundException;
-import in.koreatech.koin.domain.member.model.Member;
-import org.springframework.data.repository.query.Param;
-
-public interface AdminMemberRepository extends Repository {
-
- @EntityGraph(attributePaths = {"track"})
- @Query("select m from Member m where m.track.name = :trackName and m.isDeleted = :isDeleted")
- Page findAllByTrackAndIsDeleted(
- @Param("trackName") String trackName,
- @Param("isDeleted") Boolean isDeleted,
- Pageable pageable);
-
- @EntityGraph(attributePaths = {"track"})
- @Query("select count(m) from Member m where m.track.name = :trackName and m.isDeleted = :isDeleted")
- Integer countAllByTrackAndIsDeleted(
- @Param("trackName") String trackName,
- @Param("isDeleted") Boolean isDeleted);
-
- Member save(Member member);
-
- List findByTrackId(Integer id);
-
- @EntityGraph(attributePaths = {"track"})
- Optional findByName(String name);
-
- default Member getByName(String name) {
- return findByName(name)
- .orElseThrow(() -> MemberNotFoundException.withDetail("name: " + name));
- }
-
- @EntityGraph(attributePaths = {"track"})
- Optional findById(Integer id);
-
- default Member getById(Integer id) {
- return findById(id)
- .orElseThrow(() -> MemberNotFoundException.withDetail("id: " + id));
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/repository/AdminTechStackRepository.java b/src/main/java/in/koreatech/koin/admin/member/repository/AdminTechStackRepository.java
deleted file mode 100644
index 9ae8143173..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/repository/AdminTechStackRepository.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package in.koreatech.koin.admin.member.repository;
-
-import java.util.List;
-import java.util.Optional;
-
-import org.springframework.data.repository.Repository;
-
-import in.koreatech.koin.admin.member.exception.TechStackNotFoundException;
-import in.koreatech.koin.domain.member.model.TechStack;
-
-public interface AdminTechStackRepository extends Repository {
-
- TechStack save(TechStack techStack);
-
- Optional findById(Integer id);
-
- List findAllByTrackId(Integer id);
-
- default TechStack getById(Integer id) {
- return findById(id)
- .orElseThrow(() -> TechStackNotFoundException.withDetail("id : " + id));
- }
-}
diff --git a/src/main/java/in/koreatech/koin/admin/member/repository/AdminTrackRepository.java b/src/main/java/in/koreatech/koin/admin/member/repository/AdminTrackRepository.java
deleted file mode 100644
index 4477a2bbb7..0000000000
--- a/src/main/java/in/koreatech/koin/admin/member/repository/AdminTrackRepository.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package in.koreatech.koin.admin.member.repository;
-
-import java.util.List;
-import java.util.Optional;
-
-import org.springframework.data.repository.Repository;
-
-import in.koreatech.koin.domain.member.exception.TrackNotFoundException;
-import in.koreatech.koin.domain.member.model.Track;
-
-public interface AdminTrackRepository extends Repository