feat: 노트북-서적 간 양방향 링크/백링크 시스템 완성

 주요 기능
- 노트 ↔ 서적 문서 간 양방향 링크 생성 및 이동
- 링크 대상 타입 선택 UI (서적 문서/노트북 노트)
- 통합 백링크 시스템 (일반 문서에서 노트 백링크도 표시)
- 링크 목록 UI 개선 (상세 정보 표시, 타입 구분)

🔧 백엔드 개선
- NoteLink 모델 및 API 추가 (/note-documents/{id}/links, /note-documents/{id}/backlinks)
- 일반 문서 백링크 API에서 노트 링크도 함께 조회
- target_content_type, source_content_type 필드 추가
- 노트 문서 콘텐츠 API 추가 (/note-documents/{id}/content)

🎨 프론트엔드 개선
- text-selector.html에서 노트 문서 지원
- 링크 이동 시 contentType에 따른 올바른 URL 생성
- URL 파라미터 파싱 수정 (contentType 지원)
- 링크 타입 자동 추론 로직
- 링크 목록 UI 대폭 개선 (출발점/도착점 텍스트, 타입 배지 등)

🐛 버그 수정
- 서적 목록 로드 실패 문제 해결
- 노트에서 링크 생성 시 대상 문서 열기 문제 해결
- 더미 문서로 이동하는 문제 해결
- 캐시 관련 문제 해결
This commit is contained in:
Hyungi Ahn
2025-09-02 16:22:03 +09:00
parent f711998ce9
commit d01cdeb2f5
12 changed files with 1188 additions and 82 deletions

View File

@@ -78,11 +78,14 @@
// URL에서 문서 ID 추출
const urlParams = new URLSearchParams(window.location.search);
this.documentId = urlParams.get('id');
this.contentType = urlParams.get('contentType') || 'document'; // 기본값은 document
if (!this.documentId) {
this.showError('문서 ID가 없습니다');
return;
}
console.log('🔧 초기화:', { documentId: this.documentId, contentType: this.contentType });
// 인증 확인
if (!api.token) {
@@ -100,16 +103,28 @@
}
async loadDocument() {
console.log('📄 문서 로드 중:', this.documentId);
console.log('📄 문서 로드 중:', this.documentId, 'contentType:', this.contentType);
try {
// 문서 메타데이터 조회
const docResponse = await api.getDocument(this.documentId);
// contentType에 따라 적절한 API 호출
let docResponse, contentEndpoint;
if (this.contentType === 'note') {
// 노트 문서 메타데이터 조회
docResponse = await api.getNoteDocument(this.documentId);
contentEndpoint = `/note-documents/${this.documentId}/content`;
console.log('📝 노트 메타데이터:', docResponse);
} else {
// 일반 문서 메타데이터 조회
docResponse = await api.getDocument(this.documentId);
contentEndpoint = `/documents/${this.documentId}/content`;
console.log('📋 문서 메타데이터:', docResponse);
}
this.document = docResponse;
console.log('📋 문서 메타데이터:', docResponse);
// 문서 HTML 콘텐츠 조회
const contentResponse = await fetch(`${api.baseURL}/documents/${this.documentId}/content`, {
const contentResponse = await fetch(`${api.baseURL}${contentEndpoint}`, {
headers: {
'Authorization': `Bearer ${api.token}`,
'Content-Type': 'application/json'