Skip to content

refactor: 대학 검색 약칭 관리 분리 - #657

Merged
JanooGwan merged 7 commits into
developfrom
refactor/university-search-keyword
Jun 1, 2026
Merged

JanooGwan merged 7 commits into
developfrom
refactor/university-search-keyword

Conversation

@JanooGwan

@JanooGwan JanooGwan commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

📌 개요

  • 대학 약칭 검색어를 코드 상수에서 분리해 DB 검색 키워드 데이터로 관리하도록 리팩터링했습니다.

✅ 주요 변경 내용

  • university_search_keyword 테이블과 JPA 엔티티/리포지토리를 추가했습니다.
  • 기존 하드코딩 약칭 목록을 Flyway seed 데이터로 이전했습니다.
  • /universities, /konect/home 검색에서 대학별 관리형 키워드를 한 번에 조회해 초성/약칭 매칭에 사용하도록 변경했습니다.
  • 약칭 검색 통합 테스트가 DB 키워드 데이터를 직접 검증하도록 보강했습니다.

🧠 참고 사항

  • 초성, 캠퍼스 제거, 대학교 축약 같은 규칙 기반 토큰은 기존 matcher에서 계속 생성합니다.
  • 학교별 특수 약칭과 영문 약칭만 university_search_keyword 데이터로 관리합니다.
  • checkstyleTest는 기존 테스트 파일의 긴 줄 이슈로 실패하며, 이번 변경 파일 문제는 아닙니다.

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함
  • Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증(API 키, 환경 변수, 개인정보 등)

@coderabbitai

coderabbitai Bot commented May 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@JanooGwan, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 24 minutes and 46 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 053ac324-b693-4092-866d-f6a92337b109

📥 Commits

Reviewing files that changed from the base of the PR and between e7adc29 and 3982b59.

📒 Files selected for processing (6)
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
  • src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java
  • src/test/java/gg/agit/konect/unit/domain/university/UniversitySearchKeywordMigrationTest.java
📝 Walkthrough

Walkthrough

대학 검색 키워드를 데이터베이스에서 관리하는 엔티티와 저장소를 도입하고, UniversitySearchMatcher의 매칭 로직을 확장하여 키워드 목록을 검색 필터링에 포함하는 기능입니다. UniversityService와 WebsiteService는 키워드 조회 서비스를 통해 대학별 키워드를 미리 로드한 후 확장된 매칭 API를 호출합니다.

Changes

검색 키워드 기반 대학 검색 기능

Layer / File(s) Summary
검색 키워드 엔티티 및 저장소 정의
src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java, src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java, src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java, src/main/resources/db/migration/V86__create_university_search_keyword.sql
UniversitySearchKeywordType 열거형(ALIAS, ENGLISH_ALIAS)과 UniversitySearchKeyword JPA 엔티티를 정의하고, 대학명 컬렉션으로 키워드를 조회하는 리포지토리 메서드 및 DB 테이블(유니크 제약, 인덱스 포함)을 구성합니다.
검색 키워드 조회 서비스
src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
UniversitySearchKeywordReader는 읽기 전용 서비스로 대학명 컬렉션으로부터 Map<String, List> 형태의 대학별 키워드 목록을 조회합니다.
검색 매칭 로직 확장
src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
matches 메서드에 managedKeywords 매개변수를 추가한 오버로드를 도입하여 기본 별칭과 관리되는 키워드를 모두 포함한 토큰 집합으로 검색을 수행합니다.
서비스 레이어 통합
src/main/java/gg/agit/konect/domain/university/service/UniversityService.java, src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
UniversityService와 WebsiteService에 UniversitySearchKeywordReader 의존성을 주입받아, 검색 필터링 시 대학별 키워드 목록을 조회한 후 확장된 matches API에 전달합니다.
데이터 시드 및 테스트 지원
src/main/resources/db/migration/V87__seed_university_search_keywords.sql, src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java, src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java, src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java
DB 마이그레이션으로 각 대학의 국문·영문 약칭을 시드하고, 테스트 픽스처(UniversitySearchKeywordFixture)를 통해 검색 키워드 엔티티를 생성하며, 통합 테스트를 키워드 기반으로 재구성합니다.

Sequence Diagram

sequenceDiagram
  participant Client
  participant UniversityService
  participant KeywordReader
  participant Repository
  participant SearchMatcher
  participant Database
  Client->>UniversityService: getUniversities(query)
  UniversityService->>UniversityService: findAllUniversities()
  UniversityService->>KeywordReader: getKeywordsByUniversityName(universityNames)
  KeywordReader->>Repository: findAllByUniversityNames(universityNames)
  Repository->>Database: SELECT with JOIN FETCH university
  Database-->>Repository: List<UniversitySearchKeyword>
  Repository-->>KeywordReader: entities
  KeywordReader->>KeywordReader: groupBy koreanName + map keywords
  KeywordReader-->>UniversityService: Map<String, List<String>>
  loop for each university
    UniversityService->>SearchMatcher: matches(koreanName, query, keywords)
    SearchMatcher->>SearchMatcher: getSearchTokens(name, keywords)
    SearchMatcher->>SearchMatcher: normalizeQuery & contains check
    SearchMatcher-->>UniversityService: boolean
  end
  UniversityService-->>Client: filtered List<University>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • BCSDLab/KONECT_BACK_END#650: UniversitySearchMatcher 및 WebsiteService.getHome의 대학명·별칭 매칭 흐름 개선으로 동일한 검색 경로를 건드림
  • BCSDLab/KONECT_BACK_END#648: UniversityService의 검색 매칭 로직 확장과 동일하게 managedKeywords 기반 토큰 생성·매칭을 적용

Suggested labels

기능

Poem

🐰 검색 키워드를 데이터베이스에 담아
대학명, 초성, 약칭 모두 담아냈네
서비스 레이어 하나로 통합하니
검색이 더욱 똑똑해졌다!
키워드와 매칭의 춤을 춘다 ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목 '대학 검색 약칭 관리 분리'는 변경 사항의 핵심 목표를 명확히 나타냅니다. DB 기반의 검색 키워드 관리로 리팩터링하는 주요 변경 내용을 간결하게 요약합니다.
Description check ✅ Passed PR 설명은 변경 사항과 직접 관련이 있으며, 개요, 주요 변경 내용, 참고 사항, 체크리스트 등을 포함하여 충분히 상세합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/university-search-keyword

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JanooGwan JanooGwan self-assigned this May 31, 2026
@github-actions

github-actions Bot commented May 31, 2026 •

Copy link
Copy Markdown

🧪 JaCoCo Coverage Report (Changed Files)

Summary

  • Overall Coverage: 94.2% ✅
  • Covered Lines: 114 / 121
  • Changed Files: 7

Coverage by File

Class Coverage Lines Status
UniversitySearchMatcher
gg.agit.konect.domain.university.service
88.3% 53/60 ✅
WebsiteService
gg.agit.konect.domain.website.service
100.0% 40/40 ✅
UniversitySearchKeywordType
gg.agit.konect.domain.university.enums
100.0% 3/3 ✅
UniversityService
gg.agit.konect.domain.university.service
100.0% 11/11 ✅
UniversitySearchKeywordReader
gg.agit.konect.domain.university.service
100.0% 7/7 ✅

📊 View Workflow Run

coderabbitai[bot]
coderabbitai Bot previously requested changes May 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java`:
- Around line 49-61: getSearchTokens can NPE when managedKeywords is null
because aliases.addAll(managedKeywords) is called; update getSearchTokens (or
the callers of matches) to defensively handle a null managedKeywords by treating
it as an empty collection before calling addAll — e.g., coerce managedKeywords
to an empty List/Set (Collections.emptyList() or
Optional.ofNullable(managedKeywords).orElse(Collections.emptyList())) inside
getSearchTokens so aliases.addAll(...) never receives null; keep the rest of
getSearchTokens and matches unchanged.

In `@src/main/resources/db/migration/V86__create_university_search_keyword.sql`:
- Around line 7-12: The column keyword_type in the university_search_keyword
table is declared as VARCHAR(50) and allows values outside the expected enum
set, so add a CHECK constraint to enforce allowed values (e.g., CHECK
(keyword_type IN ('ALIAS','ENGLISH_ALIAS'))). Modify the CREATE TABLE / column
definition in V86__create_university_search_keyword.sql to include a named
constraint (suggestion: chk_university_search_keyword_keyword_type) so the DB
rejects invalid values and prevents JPA enum mapping errors at runtime; ensure
the new constraint name does not collide with existing constraints like
fk_university_search_keyword_university or
uq_university_search_keyword_university_keyword.

In `@src/main/resources/db/migration/V87__seed_university_search_keywords.sql`:
- Around line 1-232: The migration V87__seed_university_search_keywords.sql
inserts alias rows based on university.korean_name but silently succeeds when
source rows are missing; update the script to verify expected source
universities exist before inserting (e.g., SELECT COUNT(*) FROM university WHERE
korean_name IN (...)) and fail the migration if any are missing, or after INSERT
check the inserted row count against the expected count and RAISE EXCEPTION on
mismatch; target objects to modify: university_search_keyword insertion logic
and the pre/post-check queries against university.korean_name to enforce failure
when mappings are incomplete.

In
`@src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java`:
- Around line 103-107: The test currently injects aliases via
persist(UniversitySearchKeywordFixture.createAlias(...)) which masks
missing/typoes in the actual V87__seed_university_search_keywords.sql seed;
change the test to validate real seed data instead of inserting fixtures: remove
the manual alias persists in UniversityApiTest and either (a) query the seeded
university search keywords table (the rows populated by
V87__seed_university_search_keywords.sql) and assert the expected aliases exist
for the universities created by UniversityFixture.create (or for known seeded
university names), or (b) add a dedicated integration test that loads/inspects
V87__seed_university_search_keywords.sql output and verifies the /universities
search endpoint returns results for aliases like "한기대" and "과기대" without
inserting them via UniversitySearchKeywordFixture.createAlias; target the
persist, UniversitySearchKeywordFixture.createAlias and the test method in
UniversityApiTest to implement this change.

In `@src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java`:
- Around line 105-106: WebsiteApiTest currently inserts alias rows via
persist(UniversitySearchKeywordFixture.createAlias(...)) which masks problems in
the real seed script V87__seed_university_search_keywords.sql and can let
/konect/home search regressions slip through; instead remove these manual
inserts and make the test rely on the real seed data by either (a) ensuring the
DB migration/seed runner that applies V87__seed_university_search_keywords.sql
runs in the test setup (invoke the same migration/seed loader used in
production) and then assert the expected aliases exist before calling the
Website API, or (b) convert this case into an explicit integration test that
first runs the seed migration and then calls the API to verify behavior; update
WebsiteApiTest and any setup methods to run the migration/seed and remove
UniversitySearchKeywordFixture.createAlias persistence so the test validates the
actual seeded data.

In
`@src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java`:
- Around line 9-14: In UniversitySearchKeywordFixture.createAlias(), change the
locale-dependent toLowerCase() call used to build normalizedKeyword to a
locale-independent form by calling toLowerCase(Locale.ROOT) after removing
whitespace (i.e., replaceAll("\\s", "").toLowerCase(Locale.ROOT)); add the
necessary import for java.util.Locale if not already present so
normalizedKeyword is consistently normalized across locales.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6c6936b5-e50c-497b-8309-8c362572453b

📥 Commits

Reviewing files that changed from the base of the PR and between 3d8da9a and e7adc29.

📒 Files selected for processing (12)
  • src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversityService.java
  • src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
  • src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java
  • src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java
  • src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: coverage
  • GitHub Check: Analyze (java-kotlin)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Java 코드에서 import로 해결할 수 있는 경우 FQCN(Full Qualified Class Name)을 사용하지 않도록 지적한다
JPA/QueryDSL 조회 변경 시 N+1, 잘못된 fetch join, count 쿼리 왜곡, pagination 깨짐, distinct 누락을 확인한다
권한 로직은 관리자 우회, 요청자와 대상자 관계, 클럽/채팅방/공지/일정의 소속 검증이 빠지지 않았는지 확인한다
soft delete, 탈퇴 사용자, 차단/제외 조건, 중복 제거가 필요한 조회에서는 응답에 노출되면 안 되는 데이터가 포함되는지 확인한다
DTO 응답 변경은 기존 클라이언트가 기대하는 필드명, nullability, enum/string 값, 정렬 순서를 깨지 않는지 확인한다
조건이 2개 이상 결합된 비즈니스 규칙, 권한 조건, soft delete 제외, 중복 제거, fallback 우선순위, 대표값 선택, DTO 변환, count 쿼리 분리, fetch join 선택 이유처럼 코드만으로 의도가 숨겨지는 지점에는 주석을 권장한다
단순 생성자 호출, 필드 매핑, 컬렉션 반환, 이름만으로 명확한 분기에는 주석을 요구하지 않는다

Files:

  • src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java
  • src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
  • src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java
  • src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversityService.java
  • src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
**/*.{sql,java}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

데이터베이스 변경에서는 마이그레이션 순서, 기존 데이터 호환성, nullable/default 처리, 롤백 난이도, 인덱스 필요성을 확인한다

Files:

  • src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java
  • src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
  • src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java
  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversityService.java
  • src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

src/main/java/**/*.java: 아래 원칙으로 리뷰 코멘트를 작성한다.

  • 코멘트는 반드시 한국어로 작성한다.
  • 반드시 수정이 필요한 항목만 코멘트로 남기고, 단순 취향 차이는 지적하지 않는다.
  • 각 코멘트 첫 줄에 심각도를 [LEVEL: high|medium|low] 형식으로 반드시 표기한다.
  • 심각도 기준: high=운영 장애 가능, medium=품질 저하, low=개선 권고.
  • 각 코멘트는 "문제 -> 영향 -> 제안" 순서로 3문장 이내로 간결하게 작성한다.
  • 가능하면 재현 조건 및 실패 시나리오도 포함한다.
  • 제안은 현재 코드베이스(Spring Boot + JPA + Flyway) 패턴과 일치해야 한다.
  • 보안, 트랜잭션 경계, 예외 처리, N+1, 성능 회귀 가능성을 우선 점검한다.
  • 가독성: 변수/메서드 이름이 의도를 바로 드러내는지, 중첩과 메서드 길이가 과도하지 않은지 점검한다.
  • 단순화: 불필요한 추상화, 중복 로직, 과한 방어 코드가 있으면 더 단순한 대안을 제시한다.
  • 확장성: 새 요구사항 추가 시 변경 범위가 최소화되는 구조인지(하드코딩 분기/값 여부 포함) 점검한다.

Files:

  • src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java
  • src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
  • src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversityService.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
**/*

⚙️ CodeRabbit configuration file

**/*: 공통 리뷰 톤 가이드:

  • 모든 코멘트는 첫 줄에 [LEVEL: ...] 태그를 포함한다.
  • 과장된 표현 없이 사실 기반으로 작성한다.
  • 한 코멘트에는 하나의 이슈만 다룬다.
  • 코드 예시가 필요하면 최소 수정 예시를 제시한다.
  • 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.

Files:

  • src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java
  • src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java
  • src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java
  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
  • src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java
  • src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversityService.java
  • src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java
  • src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java
**/db/migration/*.sql

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Flyway 마이그레이션 파일은 파일명 버전 순서, 기존 운영 데이터 backfill, NOT NULL 추가 순서, 기본값 처리를 확인한다

Files:

  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
src/main/resources/db/migration/**/*.sql

⚙️ CodeRabbit configuration file

src/main/resources/db/migration/**/*.sql: Flyway 마이그레이션 리뷰 규칙:

  • 버전 파일명 규칙(V{number}__{description}.sql) 위반 여부를 우선 확인한다.
  • 이미 배포된 마이그레이션 수정/재번호 부여 위험이 있으면 반드시 차단 코멘트를 남긴다.
  • 파괴적 변경(drop, rename 등)은 롤백 가능성과 운영 영향 관점에서 검토한다.

Files:

  • src/main/resources/db/migration/V86__create_university_search_keyword.sql
  • src/main/resources/db/migration/V87__seed_university_search_keywords.sql
🔇 Additional comments (4)
src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java (2)

41-47: LGTM!


63-71: LGTM!

src/main/java/gg/agit/konect/domain/university/service/UniversityService.java (1)

22-37: LGTM!

src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java (1)

36-55: LGTM!

Comment thread src/main/resources/db/migration/V87__seed_university_search_keywords.sql Outdated
Comment on lines +103 to +107
University koreatech = persist(UniversityFixture.create("한국기술교육대학교", Campus.MAIN));
University seoulTech = persist(UniversityFixture.create("서울과학기술대학교", Campus.MAIN));
persist(UniversityFixture.create("서울대학교", Campus.MAIN));
persist(UniversitySearchKeywordFixture.createAlias(koreatech, "한기대"));
persist(UniversitySearchKeywordFixture.createAlias(seoulTech, "과기대"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

[LEVEL: medium]
수동 약칭 주입이 시드 마이그레이션 검증을 가립니다.

문제: 여기서 약칭 데이터를 직접 persist하면 V87__seed_university_search_keywords.sql에 누락이나 오타가 있어도 이 테스트는 계속 통과합니다. 영향: 이번 변경의 핵심인 DB 시드 회귀를 잡지 못해 운영에서만 /universities 약칭 검색이 깨질 수 있습니다. 제안: fixture insert 대신 실제 시드 데이터가 들어있는 대학으로 검증하거나, 별도 통합 테스트에서 V87 데이터와 검색 결과를 직접 확인해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java`
around lines 103 - 107, The test currently injects aliases via
persist(UniversitySearchKeywordFixture.createAlias(...)) which masks
missing/typoes in the actual V87__seed_university_search_keywords.sql seed;
change the test to validate real seed data instead of inserting fixtures: remove
the manual alias persists in UniversityApiTest and either (a) query the seeded
university search keywords table (the rows populated by
V87__seed_university_search_keywords.sql) and assert the expected aliases exist
for the universities created by UniversityFixture.create (or for known seeded
university names), or (b) add a dedicated integration test that loads/inspects
V87__seed_university_search_keywords.sql output and verifies the /universities
search endpoint returns results for aliases like "한기대" and "과기대" without
inserting them via UniversitySearchKeywordFixture.createAlias; target the
persist, UniversitySearchKeywordFixture.createAlias and the test method in
UniversityApiTest to implement this change.

Comment on lines +105 to +106
persist(UniversitySearchKeywordFixture.createAlias(koreatech, "한기대"));
persist(UniversitySearchKeywordFixture.createAlias(seoulTech, "과기대"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

[LEVEL: medium]
이 테스트도 실제 시드 데이터 대신 수동 데이터에 의존합니다.

문제: 약칭 row를 직접 넣는 방식이라 V87__seed_university_search_keywords.sql이 잘못돼도 /konect/home 검색 테스트는 그대로 통과합니다. 영향: 웹 메인 대학 검색의 핵심 회귀가 테스트에서 빠져 운영 반영 후에만 드러날 수 있습니다. 제안: 실제 시드가 적재된 데이터를 기준으로 검증하거나, 시드 데이터 존재를 먼저 보장하는 통합 테스트로 분리해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java`
around lines 105 - 106, WebsiteApiTest currently inserts alias rows via
persist(UniversitySearchKeywordFixture.createAlias(...)) which masks problems in
the real seed script V87__seed_university_search_keywords.sql and can let
/konect/home search regressions slip through; instead remove these manual
inserts and make the test rely on the real seed data by either (a) ensuring the
DB migration/seed runner that applies V87__seed_university_search_keywords.sql
runs in the test setup (invoke the same migration/seed loader used in
production) and then assert the expected aliases exist before calling the
Website API, or (b) convert this case into an explicit integration test that
first runs the seed migration and then calls the API to verify behavior; update
WebsiteApiTest and any setup methods to run the migration/seed and remove
UniversitySearchKeywordFixture.createAlias persistence so the test validates the
actual seeded data.

@JanooGwan
JanooGwan requested a review from Copilot May 31, 2026 15:57
@JanooGwan JanooGwan added 리팩토링 리팩터링을 위한 이슈입니다. and removed 리팩터링 labels May 31, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

대학 약칭 검색어를 코드 상수(UNIVERSITY_ALIASES)에서 분리하여 university_search_keyword 테이블 기반의 관리형 데이터로 이전하는 리팩터링입니다. 기존 매처는 규칙 기반 토큰 생성(초성, 캠퍼스 제거, 대학교 축약)만 유지하고, 학교별 특수/영문 약칭은 DB에서 조회한 키워드를 주입받아 사용합니다.

Changes:

  • UniversitySearchKeyword 엔티티/리포지토리/리더와 Flyway V86/V87 마이그레이션 추가 (테이블 생성 + 기존 하드코딩 약칭 seed 이전).
  • UniversitySearchMatcher에 managedKeywords를 받는 3-arg matches 오버로드 추가 및 기존 상수 맵 제거.
  • UniversityService, WebsiteService가 한 번의 조회로 대학별 키워드를 가져와 매처에 전달하도록 변경, 통합 테스트가 키워드 데이터를 명시적으로 적재하도록 갱신.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java 새 JPA 엔티티 정의 (University FK, 정규화 키워드, 타입 enum, 유니크 제약)
src/main/java/gg/agit/konect/domain/university/enums/UniversitySearchKeywordType.java ALIAS / ENGLISH_ALIAS 타입 enum 추가
src/main/java/gg/agit/konect/domain/university/repository/UniversitySearchKeywordRepository.java 학교명 IN으로 키워드와 University fetch join 조회
src/main/java/gg/agit/konect/domain/university/service/UniversitySearchKeywordReader.java 학교명 → 키워드 리스트 Map 반환, 빈 입력 시 Map.of()
src/main/java/gg/agit/konect/domain/university/service/UniversitySearchMatcher.java 하드코딩 alias 맵 제거, 외부 주입 키워드를 받는 3-arg 오버로드 도입
src/main/java/gg/agit/konect/domain/university/service/UniversityService.java 대학 목록과 키워드를 합쳐 매처에 전달하도록 변경
src/main/java/gg/agit/konect/domain/website/service/WebsiteService.java /konect/home 흐름에서도 동일하게 관리형 키워드 사용
src/main/resources/db/migration/V86__create_university_search_keyword.sql 새 테이블 + 유니크/인덱스 생성
src/main/resources/db/migration/V87__seed_university_search_keywords.sql 기존 약칭 상수를 DB seed로 이전
src/test/java/gg/agit/konect/support/fixture/UniversitySearchKeywordFixture.java 통합 테스트용 alias 키워드 fixture
src/test/java/gg/agit/konect/integration/domain/university/UniversityApiTest.java alias 검색 테스트가 키워드 행을 직접 persist하도록 갱신
src/test/java/gg/agit/konect/integration/domain/website/WebsiteApiTest.java 웹사이트 home 검색 테스트가 University + 키워드를 함께 적재

Comment thread src/main/java/gg/agit/konect/domain/university/model/UniversitySearchKeyword.java Dismissed
@JanooGwan
JanooGwan merged commit 2c9c6d1 into develop Jun 1, 2026
5 checks passed
@JanooGwan
JanooGwan deleted the refactor/university-search-keyword branch June 1, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

리팩토링 리팩터링을 위한 이슈입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants