docs: .claude 문서 세팅#2
Conversation
📝 Walkthrough📋 전체 요약교내 시설 길찾기 백엔드의 완전한 설계 문서 세트를 추가합니다. DRAFT.md 초안 기반 PLAN.md 계획부터 시스템 아키텍처, 인프라 설정, 데이터 모델, REST API 계약, 검색/라우팅 서비스 설계까지 정의합니다. 변경사항캠퍼스 길찾기 시스템 설계
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 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 @.claude/API.md:
- Around line 31-40: The markdown code fences in the API examples lack language
tags, triggering markdownlint MD040; update the example block that shows "GET
/api/search/autocomplete" to use explicit fenced languages (use ```http for the
request block and ```json for the response block), and apply the same fix to all
other API example/request/response/code fences throughout the file so request
examples use ```http, JSON responses use ```json, and plain lists or endpoints
use ```text.
- Around line 172-174: Extend the existing `@RestControllerAdvice` exception
mapping that currently handles MethodArgumentNotValidException to also handle
MissingServletRequestParameterException, MethodArgumentTypeMismatchException,
and ConstraintViolationException so GET query/param errors always return HTTP
400 with the standardized body {"error": {"code": "...", "message": "..."}};
update the global handler (the class that defines the
MethodArgumentNotValidException handler) to add specific `@ExceptionHandler`
methods (or a single handler accepting multiple exception types) that map those
three exceptions to a 400 response, normalize the error.code and error.message
fields to match the existing 4xx contract, and ensure
ConstraintViolationException translates constraint details into a readable
message for the response.
- Around line 128-130: Add a runtime guard that prevents the unauthenticated
admin endpoints under "/api/admin/**" from being active when the application
runs with the production profile; implement a startup check that reads the
active Spring profile (e.g., "prod" or spring.profiles.active) and either
unregisters/disables the "/api/admin/**" endpoints or fails application startup
with a clear error if those routes are still enabled, so the unauthenticated
admin API cannot be deployed to prod by accident.
In @.claude/ARCHITECTURE.md:
- Around line 41-64: Add explicit fenced-code languages to the two code blocks
to satisfy MD040: for the package tree block that starts with
"com.honggwart.map" (which lists MapApplication.java, config/, domain/, search/,
routing/, admin/) prefix the opening ``` with a language like text (```text),
and for the architecture/diagram block later (the other fenced block covering
the architecture diagram) choose an appropriate language tag such as text or
mermaid (e.g., ```mermaid if it is a diagram). Ensure both fenced blocks include
the language identifier and re-run linting.
In @.claude/DATA_MODEL.md:
- Around line 115-123: The fenced code block showing the Node(...) and Edge(...)
examples in .claude/DATA_MODEL.md is missing a language identifier, triggering
markdownlint MD040; update that fenced block by adding a language tag (e.g.,
"text") after the opening ``` so the block beginning with the lines containing
Node(id=701, floor=1, type=VERTICAL_LINK) and Edge(701→702, ...) is ```text to
silence MD040 and keep formatting consistent.
- Around line 59-63: The place_entrance CREATE TABLE references node(id) but is
defined before the node table, causing DDL failures when running sections in
order; either move the place_entrance block after the node table (e.g., into §2)
or add an explicit note next to the place_entrance definition stating that
execution must follow the INFRASTRUCTURE.md section order (so node is created
first). Update the document by relocating the place_entrance DDL or inserting a
short sentence referencing INFRASTRUCTURE.md execution order immediately above
the place_entrance CREATE TABLE to ensure node exists before the foreign key is
created.
In @.claude/ROUTING.md:
- Around line 58-67: The markdown code fences in ROUTING.md lack language tags
causing MD040; update the fenced blocks around the algorithm and signature by
adding appropriate language identifiers (e.g., change the algorithm block
starting with "입력: Set<Long> sources, Set<Long> targets, RoutingMode mode" to
use ```text and the method/signature examples to use ```java), and apply the
same fixes to the other code fences referenced (ranges 103-107 and 115-123) so
all triple-backtick blocks include a proper language tag.
- Around line 50-54: GraphRegistry.reload() needs a clear concurrency strategy:
build a new immutable adjacency structure off-thread (e.g., construct a fresh
Map<Long, List<EdgeRef>> via GraphLoader), then perform an atomic swap into the
live reference so in-flight routing reads (ApplicationRunner/GraphRegistry
readers) always see either the old or the new snapshot; do not mutate the live
map in place. Concretely, make the live graph reference a single
volatile/AtomicReference (or use copy-on-write semantics) that readers access
(e.g., GraphRegistry.getGraph()/route methods), ensure Edge.bidirectional logic
is applied while building the new map, and replace the reference only after the
full rebuild completes so reload() is a full rebuild-then-swap operation.
- Around line 84-85: Clarify and fix the FLOOR_CHANGE transport contract by
explicitly specifying whether RAMP is allowed and how it maps from
edge.edge_type into meta.transport: update the FLOOR_CHANGE row to list the full
allowed transport enum (e.g., STAIRS, ELEVATOR, RAMP) and add a deterministic
mapping rule from edge.edge_type → meta.transport (for example: edge.edge_type
"STAIR"/"ELEVATOR"/"RAMP" map to meta.transport STAIRS/ELEVATOR/RAMP), and if
RAMP is disallowed state that explicitly and remove it from the enum; ensure the
description and the example message generation (the "{계단/엘리베이터}" placeholder)
are updated to include or exclude RAMP accordingly and align with the
meta.transport enum/API contract referenced in FLOOR_CHANGE and edge.edge_type.
In @.claude/SEARCH.md:
- Around line 70-73: The phrase "공백 제거 또는 단일화" in the SEARCH.md normalization
rules is ambiguous; update that line to a single, unambiguous rule "공백 단일화" to
match the API contract, and ensure any surrounding text (the analyzer chain
description) consistently states that whitespace is normalized (공백 단일화) during
indexing and querying; reference the exact token "공백 제거 또는 단일화" to locate and
replace it and mention "API.md" where applicable so both docs agree.
- Around line 96-105: The markdown has fenced code blocks without a language tag
(triggering MD040); update each triple-backtick block in this section (the
blocks around the procedure at lines shown and the similar block at 111-122) to
include a language identifier such as ```text or ```pseudo so the linter stops
flagging MD040; ensure you apply the same change to both occurrences and keep
the content unchanged except for adding the language token.
- Around line 63-74: The document currently omits a char_filter chain needed to
guarantee NFC normalization and space collapse for the `nori` analyzer; update
the analyzer configuration to include a reusable char_filter sequence (e.g. an
`icu_normalizer` named like `nfc_normalizer` and a `pattern_replace` named like
`collapse_spaces`) and create a composed analyzer (e.g.
`nori_nfc_space_collapsed`) that lists those char_filters before
`nori_tokenizer` and the existing `nori` filters; then reference that composed
analyzer for the `tokens` and `ngram_tokens` (or ensure equivalent analyzer
variants are used for both indexing and querying) so the same transformation is
applied on both index and query paths.
In `@DRAFT.md`:
- Around line 59-66: Add explicit fenced-code language tags to the markdown
blocks that currently lack them: change the triple-backtick markers around the
ASCII diagram starting with "[검색 영역] [그래프 영역]" to ```text
(or ```mermaid if it's a mermaid diagram), and change the triple-backtick
markers around the JSON example beginning with "{"suggestions":" to ```json;
apply the same pattern to the other similar blocks (the autocomplete/index block
labeled "SearchToken (자동완성 색인)" and any other plain-text or code examples) so
each fenced code block has an appropriate language identifier (text, json,
mermaid, etc.).
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8487bc33-b8fd-43da-8b48-d99ffea33cef
📒 Files selected for processing (8)
.claude/API.md.claude/ARCHITECTURE.md.claude/DATA_MODEL.md.claude/INFRASTRUCTURE.md.claude/PLAN.md.claude/ROUTING.md.claude/SEARCH.mdDRAFT.md
| ``` | ||
| GET /api/search/autocomplete?q=T&limit=10 | ||
| → 200 | ||
| { | ||
| "suggestions": [ | ||
| { "placeId": 101, "displayName": "공학관 501호", "kind": "ROOM", "category": "OFFICE" }, | ||
| { "placeId": 1, "displayName": "공학관", "kind": "BUILDING" } | ||
| ] | ||
| } | ||
| ``` |
There was a problem hiding this comment.
코드 블록 언어 태그를 명시해 markdownlint(MD040) 경고를 제거해 주세요.
예: API 예시는 ```http, JSON 응답은 ```json, 엔드포인트 목록은 ```text로 지정하면 됩니다.
Also applies to: 49-63, 72-97, 134-142, 146-153, 157-160
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 31-31: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 @.claude/API.md around lines 31 - 40, The markdown code fences in the API
examples lack language tags, triggering markdownlint MD040; update the example
block that shows "GET /api/search/autocomplete" to use explicit fenced languages
(use ```http for the request block and ```json for the response block), and
apply the same fix to all other API example/request/response/code fences
throughout the file so request examples use ```http, JSON responses use ```json,
and plain lists or endpoints use ```text.
| ### §3. 관리자 API (1차: 인증 없음) | ||
|
|
||
| `/api/admin/**` 하위. **인증 미적용** — 1차 프로토타입 한정. 운영 전 Spring Security 도입 필수. |
There was a problem hiding this comment.
무인증 관리자 API는 운영 환경 강제 차단 규칙이 필요합니다.
“운영 전 도입 필수” 문구만으로는 배포 실수를 막지 못합니다. prod 프로파일에서 /api/admin/** 비활성화(또는 앱 시작 실패) 같은 강제 가드를 계약에 추가해 주세요.
Also applies to: 168-168
🤖 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 @.claude/API.md around lines 128 - 130, Add a runtime guard that prevents the
unauthenticated admin endpoints under "/api/admin/**" from being active when the
application runs with the production profile; implement a startup check that
reads the active Spring profile (e.g., "prod" or spring.profiles.active) and
either unregisters/disables the "/api/admin/**" endpoints or fails application
startup with a clear error if those routes are still enabled, so the
unauthenticated admin API cannot be deployed to prod by accident.
| - DTO에는 Bean Validation(`@NotNull`, `@Positive` 등)을 적용. | ||
| - `@RestControllerAdvice`로 `MethodArgumentNotValidException` → 400, `EntityNotFoundException` 등 → 404로 매핑. | ||
| - 응답 일관성: 모든 4xx/5xx는 `{ "error": { "code": "...", "message": "..." } }` 형태. |
There was a problem hiding this comment.
쿼리 파라미터 검증 예외 매핑이 누락되어 400 계약이 깨질 수 있습니다.
현재 매핑 정의만으로는 q 누락/mode 타입 불일치 같은 GET 파라미터 오류가 400으로 일관 처리되지 않을 수 있습니다. MissingServletRequestParameterException, MethodArgumentTypeMismatchException, ConstraintViolationException도 400으로 명시해 주세요.
🤖 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 @.claude/API.md around lines 172 - 174, Extend the existing
`@RestControllerAdvice` exception mapping that currently handles
MethodArgumentNotValidException to also handle
MissingServletRequestParameterException, MethodArgumentTypeMismatchException,
and ConstraintViolationException so GET query/param errors always return HTTP
400 with the standardized body {"error": {"code": "...", "message": "..."}};
update the global handler (the class that defines the
MethodArgumentNotValidException handler) to add specific `@ExceptionHandler`
methods (or a single handler accepting multiple exception types) that map those
three exceptions to a 400 response, normalize the error.code and error.message
fields to match the existing 4xx contract, and ensure
ConstraintViolationException translates constraint details into a readable
message for the response.
| ``` | ||
| com.honggwart.map | ||
| ├── MapApplication.java | ||
| ├── config/ | ||
| │ ├── ElasticsearchConfig.java | ||
| │ └── JpaConfig.java | ||
| ├── domain/ | ||
| │ ├── place/ # Place, PlaceAlias, PlaceEntrance, PlaceKind | ||
| │ ├── graph/ # Node, Edge, NodeType, EdgeType | ||
| │ └── common/ # 공통 enum, 값 객체 | ||
| ├── search/ | ||
| │ ├── api/ # SearchController, DTO | ||
| │ ├── service/ # SearchService(인터페이스), ESSearchService | ||
| │ ├── indexer/ # PlaceIndexer (트랜잭션 이벤트 리스너) | ||
| │ └── es/ # ES 도큐먼트, repository | ||
| ├── routing/ | ||
| │ ├── api/ # RouteController, DTO | ||
| │ ├── service/ # RouteService, RoutingMode | ||
| │ ├── graph/ # GraphRegistry(인메모리 그래프), GraphLoader | ||
| │ ├── algorithm/ # Dijkstra, WeightPolicy | ||
| │ └── instruction/ # StepExtractor, BearingCalculator | ||
| └── admin/ | ||
| └── api/ # AdminController (CRUD) | ||
| ``` |
There was a problem hiding this comment.
다이어그램 코드 블록에 언어를 지정해 주세요.
Line 41, Line 70의 fenced code block에 언어 지정이 없어 markdownlint(MD040) 경고가 납니다. 예를 들어 패키지 트리는 text, 아키텍처 다이어그램은 text 또는 mermaid로 명시해 주세요.
Also applies to: 70-108
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 41-41: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 @.claude/ARCHITECTURE.md around lines 41 - 64, Add explicit fenced-code
languages to the two code blocks to satisfy MD040: for the package tree block
that starts with "com.honggwart.map" (which lists MapApplication.java, config/,
domain/, search/, routing/, admin/) prefix the opening ``` with a language like
text (```text), and for the architecture/diagram block later (the other fenced
block covering the architecture diagram) choose an appropriate language tag such
as text or mermaid (e.g., ```mermaid if it is a diagram). Ensure both fenced
blocks include the language identifier and re-run linting.
| CREATE TABLE place_entrance ( | ||
| id BIGSERIAL PRIMARY KEY, | ||
| place_id BIGINT NOT NULL REFERENCES place(id) ON DELETE CASCADE, | ||
| node_id BIGINT NOT NULL REFERENCES node(id), | ||
| label VARCHAR(50) NOT NULL, -- "정문", "후문", "3층 연결통로" 등 |
There was a problem hiding this comment.
place_entrance FK가 node 선행 생성을 전제로 해서, 섹션 순서대로 실행하면 실패합니다.
현재 §1 블록만 따라가면 node 테이블이 아직 없어 DDL이 깨집니다. place_entrance를 §2 이후로 옮기거나, “실행 순서는 INFRASTRUCTURE.md의 순서를 따른다”를 이 위치에 명시해 주세요.
수정 예시 (문서 명시 보강)
CREATE TABLE place_entrance (
id BIGSERIAL PRIMARY KEY,
place_id BIGINT NOT NULL REFERENCES place(id) ON DELETE CASCADE,
node_id BIGINT NOT NULL REFERENCES node(id),
label VARCHAR(50) NOT NULL, -- "정문", "후문", "3층 연결통로" 등
is_primary BOOLEAN NOT NULL DEFAULT false,
UNIQUE(place_id, node_id)
);
CREATE INDEX idx_place_entrance_place ON place_entrance(place_id);
+
+-- 주의: 실제 V1 마이그레이션에서는 node/edge 생성 후 place_entrance를 생성한다.🤖 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 @.claude/DATA_MODEL.md around lines 59 - 63, The place_entrance CREATE TABLE
references node(id) but is defined before the node table, causing DDL failures
when running sections in order; either move the place_entrance block after the
node table (e.g., into §2) or add an explicit note next to the place_entrance
definition stating that execution must follow the INFRASTRUCTURE.md section
order (so node is created first). Update the document by relocating the
place_entrance DDL or inserting a short sentence referencing INFRASTRUCTURE.md
execution order immediately above the place_entrance CREATE TABLE to ensure node
exists before the foreign key is created.
| | FLOOR_CHANGE | 인접 노드의 `floor` 변화 | "{n}층까지 {계단/엘리베이터}로 이동하세요" — edge.edge_type으로 transport 결정 | | ||
| | TURN_LEFT | 회전 발생 노드의 `is_indoor=false` && Δ ≤ -τ | "좌회전 후 직진하세요" | |
There was a problem hiding this comment.
FLOOR_CHANGE transport 계약과 edge_type 범위를 맞춰야 합니다.
현재 설계에는 RAMP가 존재하지만 FLOOR_CHANGE 설명은 계단/엘리베이터 중심입니다. 층 변경에 RAMP가 허용되는지, 허용된다면 meta.transport enum/API 계약에 어떻게 표현할지 명확히 고정해 주세요.
Also applies to: 111-111
🤖 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 @.claude/ROUTING.md around lines 84 - 85, Clarify and fix the FLOOR_CHANGE
transport contract by explicitly specifying whether RAMP is allowed and how it
maps from edge.edge_type into meta.transport: update the FLOOR_CHANGE row to
list the full allowed transport enum (e.g., STAIRS, ELEVATOR, RAMP) and add a
deterministic mapping rule from edge.edge_type → meta.transport (for example:
edge.edge_type "STAIR"/"ELEVATOR"/"RAMP" map to meta.transport
STAIRS/ELEVATOR/RAMP), and if RAMP is disallowed state that explicitly and
remove it from the enum; ensure the description and the example message
generation (the "{계단/엘리베이터}" placeholder) are updated to include or exclude RAMP
accordingly and align with the meta.transport enum/API contract referenced in
FLOOR_CHANGE and edge.edge_type.
| - 한글 분석기: `nori` (Elasticsearch nori plugin) 또는 standard + ngram 조합. 1차에는 nori 사용. | ||
| - `tokens` 필드: 색인 시점에 펼친 모든 표기를 그대로 색인. analyzer는 keyword에 가까운 형태(공백·소문자 정규화 후 그대로). | ||
| - `ngram_tokens` 필드: prefix 자동완성용 `edge_ngram` analyzer (min=1, max=10). | ||
| - 동의어 처리는 **색인 시점 토큰 확장에 의존**한다. ES synonym filter는 사용하지 않는다(일관성 단일 원천). | ||
|
|
||
| **입력 정규화 (질의·색인 양쪽 공통)** | ||
|
|
||
| - 유니코드 NFC. | ||
| - 영문 소문자화. | ||
| - 공백 제거 또는 단일화. | ||
| - analyzer chain에서 일괄 처리하여 색인·질의 시 동일 변환 보장. | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Elasticsearch 8.x에서 nori analyzer만으로 Unicode NFC 정규화와 공백 단일화(다중 공백을 단일 공백으로) 처리가 가능한가? 불가능하면 권장되는 analyzer/char_filter 설정 예시는 무엇인가?
💡 Result:
결론: Elasticsearch 8.x에서 “nori analyzer만”으로 Unicode NFC 정규화와 공백 단일화(다중 공백→단일 공백)까지 모두 처리하는 것은 권장/보장된 방식이 아닙니다. nori는 형태소 분석을 위한 nori_tokenizer 및 nori 전용 token filter 조합이며, Unicode 정규화/공백 정규화는 별도의 char_filter(또는 ICU 계열 플러그인)로 전처리하는 구성이 일반적으로 필요합니다. 근거 1) nori의 구성 nori analyzer는 nori_tokenizer와 nori 전용 token filter(예: nori_part_of_speech, nori_readingform 등) 및 lowercase 같은 토큰 필터 조합으로 설명됩니다. 즉 nori가 “Unicode NFC 정규화”나 “다중 공백→단일 공백” 같은 전처리까지 내장해서 제공한다고 명시되어 있지 않습니다. [1] 근거 2) Unicode 정규화는 ICU normalization(또는 Normalization character filter) 같은 별도 컴포넌트가 필요 Elasticsearch은 ICU normalization에서 nfc 같은 정규화 옵션을 제공(icu_normalizer char filter 또는 token filter)하며, NFC/NFKC 등 정규화 모드를 name 파라미터로 지정할 수 있다고 설명합니다. 또한 “Normalization character filter를 prefer”하라고 안내합니다. [2] 근거 3) 다중 공백 단일화는 pattern_replace 같은 char_filter로 구현 Elasticsearch의 pattern_replace character filter는 정규식으로 치환을 수행하며 char_filter로 사용할 수 있습니다. [3] 권장 예시(2가지 옵션) 옵션 A) ICU 플러그인(권장): NFC 정규화 + 다중 공백 단일화 - ICU normalization은 NFC를 name="nfc"로 지정할 수 있습니다. [2] - 공백 단일화는 pattern_replace char_filter로 구현합니다. [3] 예시 설정(인덱스 분석 설정): { "settings": { "analysis": { "char_filter": { "nfc_normalizer": { "type": "icu_normalizer", "name": "nfc" }, "collapse_spaces": { "type": "pattern_replace", "pattern": " +", "replacement": " " } }, "analyzer": { "nori_nfc_space_collapsed": { "char_filter": ["nfc_normalizer", "collapse_spaces"], "tokenizer": "nori_tokenizer", "filter": [ "nori_part_of_speech", "nori_readingform", "lowercase" ] } } } } } 주의: 위에서 필터 이름/구성은 “nori analyzer가 구성된 방식”을 따라야 하며, nori_part_of_speech, nori_readingform 등의 실제 세부 설정(stoptags, decompound_mode 등)은 사용자 목적에 맞게 조정해야 합니다. nori analyzer 구성 요소가 tokenizer/전용 token filter/일부 내장 필터로 이뤄진다는 점은 nori 문서에서 확인됩니다. [1] 옵션 B) ICU normalization token filter로 NFC만 하고, 공백은 별도 char_filter로 - ICU normalization은 token filter로도 제공되며(icu_normalizer token filter), name 파라미터로 nfc를 지정 가능합니다. [2] - 다만, 공백 단일화는 어쨌든 char_filter로 하는 편이 일반적입니다(pattern_replace는 char_filter로 동작). [3] 요약 - nori analyzer “단독”으로 NFC 정규화/공백 단일화까지 모두 처리된다고 보기 어렵고, 실제로는 char_filter 또는 ICU normalization 같은 별도 구성요소를 전처리에 추가하는 방식이 권장됩니다. [2][1][3] - NFC: icu_normalizer char_filter name="nfc" 사용 [2] - 다중 공백→단일 공백: pattern_replace char_filter pattern=" +" replacement=" " 사용 [3]
Citations:
- 1: https://fossies.org/linux/elasticsearch/docs/plugins/analysis.asciidoc
- 2: https://www.elastic.co/docs/reference/elasticsearch/plugins/analysis-icu-normalization
- 3: https://www.elastic.co/guide/en/elasticsearch/reference/8.19/analysis-pattern-replace-charfilter.html
nori 단독으로는 NFC/공백 단일화 보장 불가—char_filter 구성을 문서에 명시 필요
- Elasticsearch 8.x 기준으로 nori analyzer(nori_tokenizer + nori 전용 token filter)는 형태소 분석 중심이라 NFC 정규화와 다중 공백→단일 공백 같은 전처리는 별도 char_filter로 처리하는 구성이 일반적/권장됨.
- 문서에 질의·색인 양쪽 “동일 변환”이 성립하도록
char_filter체인을 명시해 주세요(예:icu_normalizer로name="nfc", 공백은pattern_replace로" +"→" ").
"char_filter": {
"nfc_normalizer": { "type": "icu_normalizer", "name": "nfc" },
"collapse_spaces": { "type": "pattern_replace", "pattern": " +", "replacement": " " }
},
"analyzer": {
"nori_nfc_space_collapsed": {
"char_filter": ["nfc_normalizer", "collapse_spaces"],
"tokenizer": "nori_tokenizer",
"filter": ["nori_part_of_speech", "nori_readingform", "lowercase"]
}
}🤖 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 @.claude/SEARCH.md around lines 63 - 74, The document currently omits a
char_filter chain needed to guarantee NFC normalization and space collapse for
the `nori` analyzer; update the analyzer configuration to include a reusable
char_filter sequence (e.g. an `icu_normalizer` named like `nfc_normalizer` and a
`pattern_replace` named like `collapse_spaces`) and create a composed analyzer
(e.g. `nori_nfc_space_collapsed`) that lists those char_filters before
`nori_tokenizer` and the existing `nori` filters; then reference that composed
analyzer for the `tokens` and `ngram_tokens` (or ensure equivalent analyzer
variants are used for both indexing and querying) so the same transformation is
applied on both index and query paths.
| - 유니코드 NFC. | ||
| - 영문 소문자화. | ||
| - 공백 제거 또는 단일화. | ||
| - analyzer chain에서 일괄 처리하여 색인·질의 시 동일 변환 보장. |
There was a problem hiding this comment.
공백 정규화 규칙이 모호합니다(“제거 또는 단일화”).
구현체마다 다르게 해석될 수 있으니 한 가지 규칙으로 고정해 주세요. API 계약(API.md)과 맞춰 “공백 단일화”로 통일하는 편이 안전합니다.
🤖 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 @.claude/SEARCH.md around lines 70 - 73, The phrase "공백 제거 또는 단일화" in the
SEARCH.md normalization rules is ambiguous; update that line to a single,
unambiguous rule "공백 단일화" to match the API contract, and ensure any surrounding
text (the analyzer chain description) consistently states that whitespace is
normalized (공백 단일화) during indexing and querying; reference the exact token "공백
제거 또는 단일화" to locate and replace it and mention "API.md" where applicable so
both docs agree.
| ``` | ||
| 1. PlaceService(또는 AdminController의 변경 핸들러)에서 | ||
| Place/Alias/Entrance 저장 직후 PlacePersistedEvent(placeId) 발행. | ||
| 2. @TransactionalEventListener(phase = AFTER_COMMIT) 메서드가 이벤트 수신. | ||
| 3. PlaceRepository 등으로 Place + aliases + parent + parent aliases 조회. | ||
| 4. TokenGenerator.generate(...) → tokens 리스트. | ||
| 5. PlaceDocument 생성 후 PlaceSearchRepository.save(...) (upsert). | ||
| 6. 동기 실행이므로 트랜잭션 호출자가 결과를 기다림. | ||
| 7. 실패 시 1차에서는 로그만 남기고 알림/재시도 미구현. | ||
| ``` |
There was a problem hiding this comment.
fenced code block에 언어를 지정해 주세요(MD040).
예: 절차 설명은 ```text, 의사코드는 ```text 또는 ```pseudo로 통일하면 lint 경고를 제거할 수 있습니다.
Also applies to: 111-122
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 96-96: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 @.claude/SEARCH.md around lines 96 - 105, The markdown has fenced code blocks
without a language tag (triggering MD040); update each triple-backtick block in
this section (the blocks around the procedure at lines shown and the similar
block at 111-122) to include a language identifier such as ```text or ```pseudo
so the linter stops flagging MD040; ensure you apply the same change to both
occurrences and keep the content unchanged except for adding the language token.
| ``` | ||
| [검색 영역] [그래프 영역] | ||
| Building ─< BuildingAlias Node ─< Edge | ||
| │ ▲ | ||
| └─< Place ──(entranceNodeId)──────┘ | ||
| │ | ||
| └─< SearchToken (자동완성 색인) | ||
| ``` |
There was a problem hiding this comment.
코드 펜스 언어 태그를 명시해 주세요.
Line 59, 86, 168, 190, 210, 254, 279, 298, 373의 fenced code block에 언어 식별자가 없어 markdownlint(MD040) 경고가 발생합니다. text, json, mermaid 등으로 명시하면 문서 렌더링/린트 안정성이 좋아집니다.
예시 수정
-```
+```text
[검색 영역] [그래프 영역]
...
-```
+```
-```
+```json
{
"suggestions": [
...
}
-```
+```Also applies to: 86-112, 168-173, 190-202, 210-229, 254-257, 279-290, 298-303, 373-375
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 59-59: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 `@DRAFT.md` around lines 59 - 66, Add explicit fenced-code language tags to the
markdown blocks that currently lack them: change the triple-backtick markers
around the ASCII diagram starting with "[검색 영역] [그래프 영역]"
to ```text (or ```mermaid if it's a mermaid diagram), and change the
triple-backtick markers around the JSON example beginning with "{"suggestions":"
to ```json; apply the same pattern to the other similar blocks (the
autocomplete/index block labeled "SearchToken (자동완성 색인)" and any other
plain-text or code examples) so each fenced code block has an appropriate
language identifier (text, json, mermaid, etc.).
🌱 관련 이슈
📌 작업 내용 및 특이사항
📝 참고사항
Summary by CodeRabbit
릴리스 노트