Skip to content

Commit

Permalink
카테고리 별 템플릿 개수 조회 (#1031)
Browse files Browse the repository at this point in the history
  • Loading branch information
HoeSeong123 authored Feb 23, 2025
1 parent 76ef3f4 commit 4e2d561
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 11 deletions.
25 changes: 23 additions & 2 deletions backend/src/main/java/codezap/category/domain/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicUpdate;

import codezap.global.auditing.BaseTimeEntity;
import codezap.member.domain.Member;
import lombok.AccessLevel;
Expand All @@ -20,6 +23,7 @@
import lombok.NoArgsConstructor;

@Entity
@DynamicUpdate
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(
Expand All @@ -36,6 +40,7 @@
public class Category extends BaseTimeEntity {

private static final String DEFAULT_CATEGORY_NAME = "카테고리 없음";
private static final long DEFAULT_TEMPLATE_COUNT = 0L;
private static final int DEFAULT_CATEGORY_ORDINAL = 0;

@Id
Expand All @@ -54,12 +59,17 @@ public class Category extends BaseTimeEntity {
@Column(nullable = false)
private int ordinal;

@Column
@ColumnDefault("0")
private long templateCount;


public Category(String name, Member member, int ordinal) {
this(null, member, name, false, ordinal);
this(null, member, name, false, ordinal, DEFAULT_TEMPLATE_COUNT);
}

public static Category createDefaultCategory(Member member) {
return new Category(null, member, DEFAULT_CATEGORY_NAME, true, DEFAULT_CATEGORY_ORDINAL);
return new Category(null, member, DEFAULT_CATEGORY_NAME, true, DEFAULT_CATEGORY_ORDINAL, DEFAULT_TEMPLATE_COUNT);
}

public boolean hasAuthorization(Member member) {
Expand All @@ -74,4 +84,15 @@ public void update(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}

public void increaseTemplateCount() {
this.templateCount++;
}

public void decreaseTemplateCount() {
if (this.templateCount <= DEFAULT_TEMPLATE_COUNT) {
return;
}
this.templateCount--;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ public record FindCategoryResponse(
@Schema(description = "카테고리 이름", example = "Spring")
String name,
@Schema(description = "카테고리 순서", example = "1")
long ordinal
int ordinal,
@Schema(description = "카테고리 개수", example = "1")
long count
) {
public static FindCategoryResponse from(Category category) {
return new FindCategoryResponse(category.getId(), category.getName(), category.getOrdinal());
return new FindCategoryResponse(category.getId(), category.getName(), category.getOrdinal(), category.getTemplateCount());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,8 @@ public Template update(
Category category
) {
Template template = templateRepository.fetchById(templateId);
if (!template.matchMember(member)) {
throw new CodeZapException(ErrorCode.FORBIDDEN_ACCESS, "해당 템플릿에 대한 권한이 없습니다.");
}
validateAuthorization(member, template);
updateTemplateCount(category, template);
template.updateTemplate(
request.title(),
request.description(),
Expand All @@ -76,6 +75,15 @@ public Template update(
return template;
}

private void updateTemplateCount(Category changedCategory, Template template) {
Category originalCategory = template.getCategory();
if (originalCategory.equals(changedCategory)) {
return;
}
originalCategory.decreaseTemplateCount();
changedCategory.increaseTemplateCount();
}

@Transactional
public void deleteByMemberAndIds(Member member, List<Long> ids) {
if (ids.size() != new HashSet<>(ids).size()) {
Expand All @@ -86,9 +94,15 @@ public void deleteByMemberAndIds(Member member, List<Long> ids) {

private void deleteById(Member member, Long id) {
Template template = templateRepository.fetchById(id);
validateAuthorization(member, template);
Category category = template.getCategory();
category.decreaseTemplateCount();
templateRepository.deleteById(id);
}

private void validateAuthorization(Member member, Template template) {
if (!template.matchMember(member)) {
throw new CodeZapException(ErrorCode.FORBIDDEN_ACCESS, "해당 템플릿에 대한 권한이 없습니다.");
}
templateRepository.deleteById(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ALTER TABLE category ADD COLUMN template_count BIGINT DEFAULT 0;

UPDATE category c
SET template_count = (
SELECT COUNT(1)
FROM template t
WHERE t.category_id = c.id
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ALTER TABLE category ADD COLUMN template_count BIGINT DEFAULT 0;

UPDATE category c
SET template_count = (
SELECT COUNT(1)
FROM template t
WHERE t.category_id = c.id
);
56 changes: 56 additions & 0 deletions backend/src/test/java/codezap/category/domain/CategoryTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package codezap.category.domain;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import codezap.fixture.CategoryFixture;
import codezap.fixture.MemberFixture;
import codezap.member.domain.Member;

public class CategoryTest {

@Nested
@DisplayName("템플릿 개수 증가 성공")
class IncreaseTemplateCount {

@Test
@DisplayName("템플릿 개수 증가 성공")
void increaseTemplateCountSuccess() {
Category category = CategoryFixture.getDefaultCategory(MemberFixture.getFirstMember());

category.increaseTemplateCount();

assertThat(category.getTemplateCount()).isEqualTo(1);
}
}

@Nested
@DisplayName("템플릿 개수 감소 성공")
class DecreaseTemplateCount {

@Test
@DisplayName("템플릿 개수 감소 성공")
void decreaseTemplateCountSuccess() {
Category category = CategoryFixture.getDefaultCategory(MemberFixture.getFirstMember());

category.increaseTemplateCount();
category.increaseTemplateCount();
category.decreaseTemplateCount();

assertThat(category.getTemplateCount()).isEqualTo(1);
}

@Test
@DisplayName("템플릿 개수 감소 성공: 이미 0개인 경우에도 성공")
void decreaseTemplateCountSuccessAlreadyZero() {
Category category = CategoryFixture.getDefaultCategory(MemberFixture.getFirstMember());

category.decreaseTemplateCount();

assertThat(category.getTemplateCount()).isEqualTo(0);
}
}
}
4 changes: 2 additions & 2 deletions backend/src/test/java/codezap/fixture/CategoryFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

public class CategoryFixture {
public static Category getDefaultCategory(Member member) {
return new Category(1L, member, "카테고리 없음", true, 1);
return new Category(1L, member, "카테고리 없음", true, 1, 0);
}

public static Category getAdditionalCategory(Member member) {
return new Category(2L, member, "카테고리", false, 2);
return new Category(2L, member, "카테고리", false, 2, 0);
}

public static List<Category> getList(Member member, int size) {
Expand Down
2 changes: 1 addition & 1 deletion backend/submodules/private

0 comments on commit 4e2d561

Please sign in to comment.