콘텐츠로 이동
✍️ 수정가능누구나 고쳐도 됩니다. 고치면 하단 frontmatter의 갱신일·작성자·변경요약을 남겨 주세요.작성 Claude · 2026-06-04 · v12 재편·raw 컴파일·인간화

에디터 고도화 개발 명세 (FRD)

요지

공용 에디터(Tiptap)에 이미지·파일·링크 첨부를 더하는 구현을 정리한다. 설계의 핵심은 중복을 없앤 것이다 — 첨부 처리 로직을 한 곳(MediaAssetService/MediaAssetContentResolver)에 모아, 수업노트·Q&A·과제가 각자 만들지 않고 그대로 가져다 쓴다.

상위 PRD

기획(첨부 3종 + 기본 서식 + 공용 미디어 연결)은 prd이며, 바뀌면 이 문서도 갱신한다.

기술 접근 · 아키텍처

기능 정의

이미지 업로드 — 에디터 상단 [이미지] 클릭 또는 드래그&드롭 → 업로드 로딩 → 본문 삽입. 허용: jpg/png/gif/webp, 1개당 5MB(추후 BM 확장). 썸네일 미리보기·가로/세로 크기 조절·글자 정렬. 예외: 용량 초과 알림, 네트워크 오류 재시도.

파일 첨부 — 허용: pdf/docx/pptx/hwp/hwpx/xlsx/zip, 1개당 30MB(추후 BM 확장). 첨부 후 다운로드 링크(아이콘+파일명+용량), 다중 업로드. 예외: 미지원 확장자, 용량 초과.

링크 연결Ctrl+K 또는 버튼. 외부 링크 og 미리보기 카드, 링크/표시 문구 개별 편집, 임베드. 예외: 잘못된 URL 형식 경고.

기본 기능 — 말머리/글번호, 들여쓰기(Tab)/내어쓰기(Shift+Tab), 제목 타입(#·##·###), bold(Ctrl+B), 기울임(Ctrl+L).

공통 정책

  • 작성자·조회 권한자는 이미지/파일 다운로드 가능.
  • 비로그인 사용자는 다운로드 불가 → 접근 시 로그인 화면 라우팅, 로그인 후 원래 화면 복귀.

API · 데이터 모델

미디어 연결 구조 (BE)

MediaAssetService / MediaAssetContentResolver로 첨부를 공통 처리. 적용 리소스: 수업노트(TeachingNoteteaching-note), Q&A(qna), 과제(과제관리).

  • TargetType에 리소스 타입 추가.
  • 생성/수정: 요청 DTO에 mediaIds 추가 → 서비스에서 mediaAssetService.attachMediaAssets(리소스 id, mediaId 리스트, targetType) 호출.
  • 본문 저장: Tiptap content에 첨부를 media://<mediaId> 참조로 저장(원본 URL 비저장).
  • 상세 조회: 응답 DTO에 ResolvedContent 추가 → mediaAssetContentResolver.resolveMediaInContent(원본)media:// 참조를 S3 presignedUrl·만료시간이 채워진 콘텐츠로 치환 반환.

의존성 · 영향 범위

수업노트(teaching-note)·Q&A(qna)·과제(과제관리)가 첨부를 공유하므로, MediaAsset이나 TargetType을 바꾸면 이 셋 모두에 영향이 간다. 실제 파일은 S3 presignedUrl로 내려주며, 버킷명·시크릿은 환경변수로만 둔다.

테스트 계획

용량·확장자·권한 경계가 핵심이라 케이스를 표로 정리해 둔다. 공통 전략은 qa-playbook을 따른다.

구분 시나리오 기대 결과
이미지 5MB 이하 PNG 정상 삽입
이미지 초과 용량 "용량 초과" 알림
파일 30MB 초과 삽입 실패, "용량 초과" 알림
파일 .hwp 정상 삽입, 다운로드 링크 표시
링크 유효하지 않은 URL "잘못된 주소입니다" 경고
비로그인 첨부파일 클릭 로그인 화면 → 원래 화면 복귀

작업 분해

완료 추적은 GitHub 이슈에서 한다.