Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 코드잽 프로덕션 v1.1.8 배포 #957

Merged
merged 10 commits into from
Dec 9, 2024
Merged
5 changes: 1 addition & 4 deletions .github/workflows/backend_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,9 @@ jobs:
if: ${{ github.ref == 'refs/heads/main' }}
needs: build
environment: Production
strategy:
matrix:
runners: [ prod_a, prod_b ]
runs-on:
- spring
- ${{ matrix.runners }}
- prod_a
steps:
- name: 체크아웃
uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ src/test/resources/application.yml
### compose ###
docker/app/*.jar
docker/.env

### QueryDSL ###
**/src/main/generated
2 changes: 1 addition & 1 deletion backend/src/main/java/codezap/global/logger/MDCFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
@Order(1)
public class MDCFilter implements Filter {

private final String CORRELATION_ID = "correlationId";
private static final String CORRELATION_ID = "correlationId";

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature()
.getName();

log.info("{}.{} 실행 {}ms", className, methodName, executionTimeMillis);
log.debug("{}.{} 실행 {}ms", className, methodName, executionTimeMillis);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ public OpenAPI openAPI() {
.servers(
List.of(
new Server()
.url("https://api.code-zap.com")
.description("운영 서버"),
.url("http://localhost:8080")
.description("로컬 서버"),
new Server()
.url("https://dev.code-zap.com")
.description("개발 서버"),
new Server()
.url("http://localhost:8080")
.description("로컬 서버")
.description("개발 서버")
)
)
.addSecurityItem(new SecurityRequirement().addList("쿠키 인증 토큰"));
Expand Down
39 changes: 25 additions & 14 deletions backend/src/main/java/codezap/tag/service/TagService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package codezap.tag.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;
Expand All @@ -25,22 +24,34 @@ public class TagService {

@Transactional
public void createTags(Template template, List<String> tagNames) {
List<Tag> existingTags = new ArrayList<>(tagRepository.findAllByNames(tagNames));
List<String> existNames = existingTags.stream()
List<Tag> existTags = tagRepository.findAllByNames(tagNames);
List<String> existNames = getExistTagNames(existTags);

List<Tag> newTags = getOnlyNewTags(existNames, tagNames);
List<Tag> savedNewTags = tagRepository.saveAll(newTags);
existTags.addAll(savedNewTags);
saveTemplateTags(template, existTags);
}

private List<String> getExistTagNames(List<Tag> existTags) {
return existTags.stream()
.map(Tag::getName)
.toList();
}

private List<Tag> getOnlyNewTags(List<String> existNames, List<String> tagNames) {
return tagNames.stream()
.distinct()
.filter(name -> !existNames.contains(name))
.map(Tag::new)
.toList();
}

List<Tag> newTags = tagRepository.saveAll(
tagNames.stream()
.filter(name -> !existNames.contains(name))
.map(Tag::new)
.toList()
);
existingTags.addAll(newTags);

for (Tag existingTag : existingTags) {
templateTagRepository.save(new TemplateTag(template, existingTag));
}
private void saveTemplateTags(Template template, List<Tag> tags) {
List<TemplateTag> templateTags = tags.stream()
.map(tag -> new TemplateTag(template, tag))
.toList();
templateTagRepository.saveAll(templateTags);
}

public List<Tag> findAllByTemplate(Template template) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class FullTextFunctionContributor implements FunctionContributor {

private static final String FUNCTION_NAME = "fulltext_match";
private static final String MATCH_AGAINST_FUNCTION = "match(?1, ?2) against(?3)";
private static final String MATCH_AGAINST_FUNCTION = "match(?1, ?2) against(?3 in boolean mode)";

@Override
public void contributeFunctions(FunctionContributions functionContributions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@

import codezap.template.domain.Visibility;
import codezap.template.repository.strategy.FullTextSearchSearchStrategy;
import codezap.template.repository.strategy.LikeSearchStrategy;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class TemplateSearchExpressionProvider {

private final LikeSearchStrategy likeSearchStrategy;
private final FullTextSearchSearchStrategy fullTextSearchStrategy;

private static final int MINIMUM_KEYWORD_LENGTH = 3;

public BooleanExpression filterMember(Long memberId) {
return Optional.ofNullable(memberId)
.map(template.member.id::eq)
Expand Down Expand Up @@ -60,15 +56,7 @@ public BooleanExpression matchesKeyword(String keyword) {
return Optional.ofNullable(keyword)
.filter(k -> !k.isBlank())
.map(String::trim)
.map(this::createKeywordMatchExpression)
.map(fullTextSearchStrategy::matchedKeyword)
.orElse(null);
}

private BooleanExpression createKeywordMatchExpression(String trimmedKeyword) {
if (trimmedKeyword.length() < MINIMUM_KEYWORD_LENGTH) {
return likeSearchStrategy.matchedKeyword(trimmedKeyword);
}

return fullTextSearchStrategy.matchedKeyword(trimmedKeyword);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import static codezap.template.domain.QSourceCode.sourceCode;
import static codezap.template.domain.QTemplate.template;

import java.util.Arrays;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;

import com.querydsl.core.types.dsl.BooleanExpression;
Expand All @@ -21,8 +24,9 @@ public class FullTextSearchSearchStrategy implements SearchStrategy {

@Override
public BooleanExpression matchedKeyword(String trimmedKeyword) {
NumberExpression<Double> titleScore = getMatchedAccuracy(template.title, template.description, trimmedKeyword);
NumberExpression<Double> sourceCodeScore = getMatchedAccuracy(sourceCode.filename, sourceCode.content, trimmedKeyword);
String parsedKeyword = parseKeyword(trimmedKeyword);
NumberExpression<Double> titleScore = getMatchedAccuracy(template.title, template.description, parsedKeyword);
NumberExpression<Double> sourceCodeScore = getMatchedAccuracy(sourceCode.filename, sourceCode.content, parsedKeyword);
return titleScore.gt(NO_MATCHED_SCORE).or(
template.id.in(JPAExpressions
.select(sourceCode.template.id)
Expand All @@ -32,6 +36,13 @@ public BooleanExpression matchedKeyword(String trimmedKeyword) {
);
}

private String parseKeyword(String trimmedKeyword) {
String[] parsedKeywords = trimmedKeyword.split(" ");
return Arrays.stream(parsedKeywords)
.map(keyword -> "+" + keyword)
.collect(Collectors.joining(" "));
}

private NumberExpression<Double> getMatchedAccuracy(Object... args) {
return Expressions.numberTemplate(Double.class,
MATCH_FUNCTION,
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion backend/src/main/resources/application-swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ springdoc:
default-produces-media-type: application/json
swagger-ui:
path: /swagger-ui.html
enabled: true
enabled: ${SWAGGER_ENABLED}
supportedSubmitMethods: get
display-request-duration: false
4 changes: 4 additions & 0 deletions backend/src/main/resources/logger/logback-spring-prod.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<appender-ref ref="console-appender"/>
</logger>

<logger name="codezap" level="INFO">
<appender-ref ref="info-appender"/>
</logger>

<root level="WARN">
<appender-ref ref="warn-appender"/>
<appender-ref ref="error-appender"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import codezap.global.rds.DataSourceConfig;
import codezap.template.repository.TemplateSearchExpressionProvider;
import codezap.template.repository.strategy.FullTextSearchSearchStrategy;
import codezap.template.repository.strategy.LikeSearchStrategy;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
Expand All @@ -29,7 +28,6 @@
DataSourceConfig.class,
QueryDSLConfig.class,
TemplateSearchExpressionProvider.class,
LikeSearchStrategy.class,
FullTextSearchSearchStrategy.class,
FixedPageCounter.class
})
Expand Down
17 changes: 17 additions & 0 deletions backend/src/test/java/codezap/tag/service/TagServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ void createTags_WhenExistTemplateTagContains() {
.containsExactlyElementsOf(tagNames);
}

@Test
@DisplayName("성공: 저장하려는 태그에 중복이 있는 경우 하나만 생성")
void createTags_WhenDuplicatedTemplateTag() {
// given
Template template = createSavedTemplate();
String tagName = "tag1";
List<String> tagNames = Arrays.asList(tagName, tagName);

// when
sut.createTags(template, tagNames);

// then
List<String> savedTemplateTagNames = getSavedTemplateTagNames(template);
assertThat(savedTemplateTagNames).hasSize(1)
.containsExactly(tagName);
}

@Test
@DisplayName("성공: 이미 있는 태그이지만 이 템플릿의 태그가 아닌 경우 템플릿 태그만 추가")
void createTags_WhenExistTagContains() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@
import codezap.template.domain.Template;
import codezap.template.domain.Visibility;
import codezap.template.repository.strategy.FullTextSearchSearchStrategy;
import codezap.template.repository.strategy.LikeSearchStrategy;

@DataJpaTest(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Repository.class), useDefaultFilters = false)
@Import({
JpaAuditingConfiguration.class,
DataSourceConfig.class,
QueryDSLConfig.class,
TemplateSearchExpressionProvider.class,
LikeSearchStrategy.class,
FullTextSearchSearchStrategy.class,
FixedPageCounter.class,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ void findAllSuccessByMemberIdAndVisibility() {
@DisplayName("검색 기능: 모든 검색 기준으로 템플릿 목록 조회 성공")
void findAllSuccessWithAllCriteria() {
Long memberId = member1.getId();
String keyword = "안녕하세요";
String keyword = "안녕";
Long categoryId = category1.getId();
List<Long> tagIds = List.of(tag1.getId(), tag2.getId());
Visibility visibility = Visibility.PUBLIC;
Expand Down
2 changes: 1 addition & 1 deletion backend/submodules/private
Loading