Skip to content

Conversation

@jk-kim0
Copy link
Contributor

@jk-kim0 jk-kim0 commented Jan 28, 2026

Description

  • <ac:link> 태그로 표현된 외부 Confluence 링크가 #target-title-not-found로 잘못 변환되던 문제를 수정합니다.
  • ri:pagespace-key 속성이 있고 해당 페이지가 pages.yaml에 없는 경우, Confluence space overview URL을 생성합니다.
    • 예: <ac:link><ri:page ri:content-title="External Page" ri:space-key="QCP"/></ac:link>
    • 이전: [External Page](#target-title-not-found)
    • 수정 후: [External Page](https://querypie.atlassian.net/wiki/spaces/QCP/overview)
  • 테스트 케이스 1844969501을 추가하여 외부 링크 변환을 검증합니다.

Background

Confluence XHTML을 MDX로 변환할 때, 변환 범위 밖의 페이지를 가리키는 <ac:link> 태그가 #target-title-not-found로 변환되어 링크가 깨지는 문제가 있었습니다.
사용자가 외부 Confluence 페이지 링크를 클릭하면 아무 동작도 하지 않는 깨진 링크가 표시되었습니다.

수정 내용

  1. SingleLineParser<ac:link> 처리 로직 수정 (confluence_xhtml_to_markdown.py:843-891)
  2. ri:page에서 space-key 속성을 확인하여 외부 링크 여부 판단
  3. 외부 링크인 경우 Confluence space overview URL 생성
  4. 테스트 케이스 추가 (confluence-mdx/tests/testcases/1844969501/)

Related tickets & links

Test plan

  • 새로운 테스트 케이스 1844969501로 외부 링크 변환 검증
  • 기존 테스트 케이스 544113141 등으로 기존 기능 정상 작동 확인
  • <a> 태그 외부 링크는 이미 정상 작동하므로 영향 없음 확인

Additional notes

  • <a> 태그로 된 외부 링크는 이미 정상적으로 원본 URL을 유지하고 있었습니다.
  • <ac:link> 태그에는 일반적으로 page_id가 없어 정확한 페이지 URL을 생성할 수 없으므로, space overview URL을 사용합니다.
  • page_id가 필요한 경우는 <a> 태그 형태로 전체 URL이 제공되므로 문제없이 처리됩니다.

🤖 Generated with Claude Code

## Description
- `<ac:link>` 태그로 표현된 외부 Confluence 링크가 `#target-title-not-found`로 잘못 변환되던 문제를 수정합니다.
- `ri:page`에 `space-key` 속성이 있고 해당 페이지가 pages.yaml에 없는 경우, Confluence space overview URL을 생성합니다.
- 테스트 케이스 `1844969501`을 추가하여 외부 링크 변환을 검증합니다.

### Background
Confluence XHTML을 MDX로 변환할 때, 변환 범위 밖의 페이지를 가리키는 `<ac:link>` 태그가 `#target-title-not-found`로 변환되어 링크가 깨지는 문제가 있었습니다.

## Related tickets & links
- #575

## Added/updated tests?
- [x] Yes
- [ ] No, and this is why: ``
- [ ] I need help with writing tests

## Additional notes
- `<a>` 태그로 된 외부 링크는 이미 정상적으로 원본 URL을 유지하고 있었습니다.
- `<ac:link>` 태그에는 일반적으로 page_id가 없어 정확한 페이지 URL을 생성할 수 없으므로, space overview URL을 사용합니다.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Jan 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
querypie-docs Ready Ready Preview, Comment Jan 28, 2026 9:34am

Request Review

## Description
- space-key 속성이 없는 `<ac:link>` 태그는 `#link-error` 앵커를 사용하여 간단한 오류 메시지를 표시합니다.
- 사용자가 링크를 클릭하면 URL 바에서 `#link-error`를 볼 수 있습니다.
- 테스트 케이스에 space-key가 없는 경우를 추가하여 검증합니다.

### 변경 내용
- space-key가 없을 때: `#link-error` 앵커 생성
- space-key가 있을 때: 해당 space의 overview URL 생성

### Before
```markdown
[Page Without Space Key](#target-title-not-found)
```

### After
```markdown
[Page Without Space Key](#link-error)
```

## Test plan
- [x] space-key가 "QCP"인 경우: QCP space overview URL ✅
- [x] space-key가 "EXTERNAL"인 경우: EXTERNAL space overview URL ✅
- [x] space-key가 없는 경우: `#link-error` ✅

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## Description
- `<ac:link><ri:space ri:space-key="QCP" /></ac:link>` 형태의 space 링크를 올바르게 처리합니다.
- 테스트 케이스 1844969501을 실제 Confluence 문서 데이터로 업데이트합니다.
  - `copy-files-to-testcases.sh` 스크립트를 사용하여 confluence-mdx/var에서 실제 데이터 복사
  - 해당 문서에는 여러 외부 Confluence 링크가 포함되어 있어 테스트에 적합합니다.

### 수정 내용
1. `ri:space` 태그 처리 로직 추가 (confluence_xhtml_to_markdown.py:868-877)
   - space-key가 있는 경우: space overview URL 생성
   - space-key가 없는 경우: \`#link-error\` 표시
2. 테스트 케이스 1844969501에 실제 문서 데이터 반영
   - page.xhtml: 실제 외부 링크 포함 (ri:space, ri:page with space-key="QCP")
   - page.v1.yaml: 실제 페이지 메타데이터
   - attachments.v1.yaml, children.v2.yaml, image 파일 등

### 테스트 결과
- ✅ `<ac:link><ri:space ri:space-key="QCP" />`: `https://querypie.atlassian.net/wiki/spaces/QCP/overview`
- ✅ `<ac:link><ri:page ri:space-key="QCP" ri:content-title="..."/>`: space overview URL
- ✅ 기존 기능 정상 작동

## Related tickets & links
- #575

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## Description
- 테스트 케이스 1844969501의 expected.mdx 파일을 추가합니다.
- 실제 Confluence 문서 데이터를 기반으로 생성된 변환 결과를 expected.mdx로 저장합니다.
- 외부 Confluence 링크 변환이 올바르게 작동하는지 검증할 수 있습니다.

### 테스트 내용
- `<ac:link><ri:space ri:space-key="QCP" />`: space overview URL로 변환 ✅
- `<ac:link><ri:page ri:space-key="QCP" ri:content-title="..."/>`: space overview URL로 변환 ✅

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jk-kim0 jk-kim0 self-assigned this Jan 28, 2026
@jk-kim0 jk-kim0 merged commit e326bfd into main Jan 28, 2026
7 checks passed
@jk-kim0 jk-kim0 deleted the feat/fix-external-confluence-links branch January 28, 2026 09:37
jk-kim0 added a commit that referenced this pull request Jan 29, 2026
## Summary

page.v1.yaml의 body.view HTML을 활용하여 외부 Confluence 링크에 대해 정확한 pageId 기반
URL을 생성합니다. 또한 코드 구조 개선을 통해 유지보수성과 가독성을 향상시켰습니다.

## Description

### 기능 구현

- **링크 매핑 빌드**: page.v1.yaml의 body.view HTML을 파싱하여 링크 텍스트 → pageId 매핑을
생성하는 `build_link_mapping()` 함수 추가
- **pageId 기반 URL 생성**: `<ac:link><ri:page>` 처리 로직에서 링크 매핑을 조회하여 정확한
pageId 기반 Confluence URL 생성
- **외부 Confluence 링크 처리** (변환 범위 외 페이지):
- pageId 있음:
`https://querypie.atlassian.net/wiki/spaces/{space_key}/pages/{page_id}`
- pageId 없음 + space_key 있음:
`https://querypie.atlassian.net/wiki/spaces/{space_key}/overview` (기존 동작
유지)
  - 둘 다 없음: `#link-error` (기존 동작 유지)

### 코드 구조 개선 (리팩토링)

- **외부 링크 처리 함수 분리**: `resolve_external_link(link_text, space_key,
target_title)` 함수로 추출
  - pageId 조회 및 URL 생성 로직 캡슐화
  - 명확한 fallback 전략 (pageId → space overview → error link)
  - `convert_recursively` 메서드 복잡도 감소 (18줄 → 3줄)

- **ac:link 변환 메서드 분리**: `SingleLineParser.convert_ac_link(node)` 메서드로
추출
  - ac:link 노드 변환 로직을 독립적인 메서드로 관리
  - 내부 링크, 외부 링크, space 링크 처리 로직 캡슐화
  - `convert_recursively` 메서드 복잡도 감소 (54줄 → 3줄)

### 문서화

- **링크 유형별 예시 추가**: `convert_ac_link` 메서드의 docstring에 6가지 링크 유형별 상세 예시
추가
  - Internal Page Link: `[User Guide](../../user-guide)`
- External Page Link with pageId: `[QueryPie
Architecture](https://querypie.atlassian.net/wiki/spaces/QCP/pages/400064797)`
- External Page Link without pageId: `[Unknown
Page](https://querypie.atlassian.net/wiki/spaces/QCP/overview)`
- Space Link: `[Confluence
Space](https://querypie.atlassian.net/wiki/spaces/QCP/overview)`
- Link with Anchor Fragment: `[My Dashboard |
section-name](../../my-dashboard#section-name)`
  - Error Case: `[Missing Page](#link-error)`

### Background

#576에서 구현한 외부 링크 처리는 space overview URL만 생성했습니다.
page.xhtml에는 pageId가 포함되지 않지만, page.v1.yaml의 body.view HTML에는
`data-linked-resource-id` 속성으로 pageId가 포함되어 있어 이를 활용합니다.

### Implementation Details

1. **링크 매핑 빌드**: `build_link_mapping()` 함수가 page.v1.yaml의 body.view
HTML을 파싱
2. **전역 변수 저장**: `GLOBAL_LINK_MAPPING`에 링크 텍스트 → pageId 딕셔너리 저장
3. **매핑 조회**: 외부 링크 처리 시 `resolve_external_link()` 함수가 링크 텍스트로 pageId 조회
4. **URL 생성**: pageId가 있으면 정확한 페이지 URL 생성, 없으면 기존 fallback 로직 사용

### Code Quality Improvements

- **관심사 분리**: 각 기능이 독립적인 함수/메서드로 관리
- **코드 가독성**: 복잡한 조건문이 명확한 함수 호출로 대체
- **유지보수성**: 변경 사항 발생 시 해당 함수/메서드만 수정
- **테스트 용이성**: 함수/메서드 단위로 테스트 작성 가능
- **문서화**: 상세한 docstring으로 사용법 및 예시 명시

## Test plan

- [x] 테스트 케이스 1844969501로 검증 완료
  - ✓ QueryPie Architecture → pages/400064797
  - ✓ Advanced Environment Setup → pages/887947577
  - ✓ Advanced Integration Guide → pages/841449834
  - ✓ 릴리스 버전 별 문서 → pages/841351486
  - ✓ Troubleshooting → pages/920486841
- [x] 기존 pytest 테스트 통과 확인 (55 passed)
- [x] expected.mdx 업데이트 완료
- [x] 리팩토링 후 출력 결과 동일성 확인

## Related tickets & links

- Closes #577
- Related to #576

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants