Skip to content

docs: .claude 문서 세팅#2

Open
AshCircle wants to merge 2 commits into
developfrom
docs/1-claude-documentation
Open

docs: .claude 문서 세팅#2
AshCircle wants to merge 2 commits into
developfrom
docs/1-claude-documentation

Conversation

@AshCircle
Copy link
Copy Markdown
Member

@AshCircle AshCircle commented May 21, 2026

🌱 관련 이슈

close #이슈번호 또는 resolve #이슈번호를 통해 자동 닫힘 처리 가능


📌 작업 내용 및 특이사항

어떤 작업을 했는지 간단히 요약해 주세요.

  • DRAFT.md 기반 PLAN.md 작성으로 프로젝트 기획 기반 백엔드 구현 포인트 정리
  • PLAN.md를 작업 단위 별 문서 인덱싱에 사용하도록 변경

📝 참고사항

리뷰어가 참고하면 좋을 만한 내용을 자유롭게 작성해 주세요.

Summary by CodeRabbit

릴리스 노트

  • Documentation
    • 캠퍼스 시설 길찾기 시스템의 전체 아키텍처, 데이터 모델, API 계약 및 구현 가이드 문서 추가
    • 검색 및 라우팅 기능, 인프라 설정, 개발 계획에 대한 상세 설계 문서 구성

Review Change Stack

@AshCircle AshCircle self-assigned this May 21, 2026
@AshCircle AshCircle added the 📝 Documentation 문서 관련 작업 label May 21, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

📋 전체 요약

교내 시설 길찾기 백엔드의 완전한 설계 문서 세트를 추가합니다. DRAFT.md 초안 기반 PLAN.md 계획부터 시스템 아키텍처, 인프라 설정, 데이터 모델, REST API 계약, 검색/라우팅 서비스 설계까지 정의합니다.

변경사항

캠퍼스 길찾기 시스템 설계

계층 / 파일 설명
설계 초안 및 구현 계획
DRAFT.md, .claude/PLAN.md
시스템 목표(캠퍼스 시설 길찾기), 기술 스택(Spring Boot/PostgreSQL/Elasticsearch/인메모리 그래프), 검색(prefix 자동완성, 정규+별칭 모델, Trie vs Elasticsearch), 라우팅(메모리 다익스트라, step 추출, bearing 회전 감지), 도메인 분할(Place↔Node 매핑), 결정 항목 11개, 권장 진행 순서를 정의합니다.
시스템 아키텍처
.claude/ARCHITECTURE.md
Spring Boot 기술 스택(Java/JPA/PostgreSQL/Flyway/EPSG:4326/Elasticsearch 8/인메모리 그래프), com.honggwart.map 하위 도메인/검색/라우팅/관리 패키지 구조, 영역 경계 다이어그램(컨트롤러→서비스→인덱서/그래프 처리→데이터모델→인프라/외부의존), 핵심 연결(PlaceEntrance를 통한 검색↔그래프 연계, 이벤트 기반 ES/그래프 동기화), 파일 매핑(INFRASTRUCTURE/DATA_MODEL/ROUTING/SEARCH/API)을 정의합니다.
인프라 및 환경 설정
.claude/INFRASTRUCTURE.md
build.gradle 의존성 추가(spring-boot-starter-data-jpa, elasticsearch-java, validation, postgresql, flyway, testcontainers), docker-compose.yml(PostgreSQL 16/5432, Elasticsearch 8/9200), application.yml(datasource/JPA/Flyway/ES URI), V1__init.sql(place→node→edge→place_alias→place_entrance 테이블 순서), 부트스트랩 검증(컨테이너 기동, 애플리케이션 실행, Flyway 적용 확인, ES 헬스 체크)을 정의합니다.
데이터 모델 및 스키마
.claude/DATA_MODEL.md
Place/PlaceAlias/PlaceEntrance/Node/Edge 5개 핵심 엔티티의 DDL, 컬럼 의미(Place.kind에 따른 nullable, display_name 파생), 제약(PlaceEntrance의 place_id-node_id 유니크), Node/Edge의 좌표/층/실내외/타입/properties(JSONB), PlaceKind/NodeType(5개 고정)/EdgeType enum, 층 간 이동(VERTICAL_LINK 노드+STAIR/ELEVATOR edge), JPA 매핑(properties @JdbcTypeCode, LAZY 기본, equals/hashCode id 기반, enum 문자열 저장), V2 시드(건물/강의실/외부시설, 노드/간선 규모), 다중 입구(is_primary), 별칭, 단위/통합 검증 시나리오를 정의합니다.
REST API 계약
.claude/API.md
검색 API(GET /api/search/autocomplete 쿼리/limit 파라미터, 400/응답 스키마, placeId 제안), 장소 조회(GET /api/places/{placeId}, 404, entrances 배열), 라우팅 API(GET /api/route, fromPlaceId/toPlaceId/mode, summary/polyline/steps 응답, StepType/FLOOR_CHANGE meta, 404/400), 관리자 API(/api/admin/**, Place/Node/Edge CRUD, 이벤트 발행, ES 색인/그래프 재빌드 동기화), 공통 처리(DTO Bean Validation, @RestControllerAdvice의 400/404 매핑, 일관된 error 스키마), MockMvc/Testcontainers 테스트, curl 수동 검증을 정의합니다.
검색 및 라우팅 서비스 설계
.claude/SEARCH.md, .claude/ROUTING.md
검색: SearchService 인터페이스(자동완성/ID 조회), places 인덱스 스키마, analyzer 및 입력 정규화(NFC/소문자/공백 단일화), TokenGenerator(건물/호실/별칭/가중치), 트랜잭션 이벤트 기반 ES upsert/삭제, ESSearchService 질의(중복 placeId 제거, 가중치 정렬), 전체 재색인, 단위/통합/수동 검증. 라우팅: RoutingMode/WeightPolicy 정의, edge 타입별 모드 가중치 표, GraphRegistry 인메모리 적재/reload, 가상 시작/종료 노드 포함 단일/다중 출발 Dijkstra, 노드열→step 변환(이벤트/회전 임계값/실내 회전 무시/방위각 계산/run-length 압축), RouteService 진입점(PlaceEntrance node_id 추출, Dijkstra 호출, polyline 매핑, StepExtractor, usedSource/usedTarget 식별, summary 산출), 단위/통합/수동 검증을 정의합니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 적절히 요약하고 있습니다. .claude 문서 설정이라는 핵심 목표를 명확히 전달합니다.
Linked Issues check ✅ Passed PR이 연결된 이슈 #1의 모든 요구사항을 충족합니다. DRAFT.md 기반 PLAN.md 생성 및 작업 단위별 마크다운 문서 생성이 완료되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #1의 범위 내에 있습니다. PLAN.md와 작업 단위별 문서(ARCHITECTURE.md, DATA_MODEL.md, INFRASTRUCTURE.md, API.md, ROUTING.md, SEARCH.md) 생성으로 정의된 목표와 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between b85ed7d and 051e967.

📒 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.md
  • DRAFT.md

Comment thread .claude/API.md
Comment on lines +31 to +40
```
GET /api/search/autocomplete?q=T&limit=10
→ 200
{
"suggestions": [
{ "placeId": 101, "displayName": "공학관 501호", "kind": "ROOM", "category": "OFFICE" },
{ "placeId": 1, "displayName": "공학관", "kind": "BUILDING" }
]
}
```
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 | 🟡 Minor | ⚡ Quick win

코드 블록 언어 태그를 명시해 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.

Comment thread .claude/API.md
Comment on lines +128 to +130
### §3. 관리자 API (1차: 인증 없음)

`/api/admin/**` 하위. **인증 미적용** — 1차 프로토타입 한정. 운영 전 Spring Security 도입 필수.
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

무인증 관리자 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.

Comment thread .claude/API.md
Comment on lines +172 to +174
- DTO에는 Bean Validation(`@NotNull`, `@Positive` 등)을 적용.
- `@RestControllerAdvice`로 `MethodArgumentNotValidException` → 400, `EntityNotFoundException` 등 → 404로 매핑.
- 응답 일관성: 모든 4xx/5xx는 `{ "error": { "code": "...", "message": "..." } }` 형태.
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

쿼리 파라미터 검증 예외 매핑이 누락되어 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.

Comment thread .claude/ARCHITECTURE.md
Comment on lines +41 to +64
```
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)
```
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 | 🟡 Minor | ⚡ Quick win

다이어그램 코드 블록에 언어를 지정해 주세요.

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.

Comment thread .claude/DATA_MODEL.md
Comment on lines +59 to +63
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층 연결통로" 등
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

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.

Comment thread .claude/ROUTING.md
Comment on lines +84 to +85
| FLOOR_CHANGE | 인접 노드의 `floor` 변화 | "{n}층까지 {계단/엘리베이터}로 이동하세요" — edge.edge_type으로 transport 결정 |
| TURN_LEFT | 회전 발생 노드의 `is_indoor=false` && Δ ≤ -τ | "좌회전 후 직진하세요" |
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

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.

Comment thread .claude/SEARCH.md
Comment on lines +63 to +74
- 한글 분석기: `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에서 일괄 처리하여 색인·질의 시 동일 변환 보장.

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

🧩 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:


nori 단독으로는 NFC/공백 단일화 보장 불가—char_filter 구성을 문서에 명시 필요

  • Elasticsearch 8.x 기준으로 nori analyzer(nori_tokenizer + nori 전용 token filter)는 형태소 분석 중심이라 NFC 정규화와 다중 공백→단일 공백 같은 전처리는 별도 char_filter로 처리하는 구성이 일반적/권장됨.
  • 문서에 질의·색인 양쪽 “동일 변환”이 성립하도록 char_filter 체인을 명시해 주세요(예: icu_normalizername="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.

Comment thread .claude/SEARCH.md
Comment on lines +70 to +73
- 유니코드 NFC.
- 영문 소문자화.
- 공백 제거 또는 단일화.
- analyzer chain에서 일괄 처리하여 색인·질의 시 동일 변환 보장.
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 | 🟡 Minor | ⚡ Quick win

공백 정규화 규칙이 모호합니다(“제거 또는 단일화”).

구현체마다 다르게 해석될 수 있으니 한 가지 규칙으로 고정해 주세요. 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.

Comment thread .claude/SEARCH.md
Comment on lines +96 to +105
```
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차에서는 로그만 남기고 알림/재시도 미구현.
```
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 | 🟡 Minor | ⚡ Quick win

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.

Comment thread DRAFT.md
Comment on lines +59 to +66
```
[검색 영역] [그래프 영역]
Building ─< BuildingAlias Node ─< Edge
│ ▲
└─< Place ──(entranceNodeId)──────┘
└─< SearchToken (자동완성 색인)
```
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 | 🟡 Minor | ⚡ Quick win

코드 펜스 언어 태그를 명시해 주세요.

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.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📝 Documentation 문서 관련 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📝 .claude 문서 세팅

1 participant