xNote 개발 명세서 v1.0

다중사용자 파일관리 · 자료관리 · 자료공유 솔루션
작성일: 2026-06-19


1. 프로젝트 개요

1.1 핵심 포지셔닝

항목 내용
제품명 xNote
포지셔닝 DSM Note Station 대체 · 독립형 자료관리 솔루션
경쟁 회피 노션·옵시디언과 직접 경쟁 안 함 → 파일 특화 뷰어 + 공유가 차별점
배포 방식 어느 서버든 설치 가능 (XAMPP, VPS, Synology 등)
대상 팀/조직 단위 다중 사용자

1.2 핵심 차별화 기능

  1. 특화 뷰어: PDF → 이북뷰어, 오디오 → 플레이어, 이미지 → 슬라이드쇼
  2. 대용량 첨부: 파일당 최대 100MB, 청크 업로드로 서버 과부하 방지
  3. 외부 임베드 공유: 이북뷰어 등 링크 공유로 외부 사이트에서 바로 서비스 가능
  4. 클라우드 연동: 구글 드라이브 파일공유 + 네이버 클라우드 폴더 파일관리

2. 기술 스택

2.1 Frontend

Vue 3 (Composition API)
├── 에디터: TipTap v2 (ProseMirror 기반)
├── 상태관리: Pinia
├── 라우팅: Vue Router 4
├── 스타일: CSS Variables (다크/라이트 테마)
├── 파일 업로드: Uppy (청크 업로드 지원)
├── PDF 뷰어: PDF.js
├── 오디오 플레이어: Howler.js
└── 이미지 슬라이더: Swiper.js

2.2 Backend

Node.js (Express)
├── DB: SQLite (better-sqlite3)
├── 인증: JWT (Access Token + Refresh Token)
├── 파일저장: 로컬 스토리지 (/data/files/)
├── 썸네일: Sharp (이미지), pdf-thumbnail (PDF)
├── 청크 업로드: Multer + 자체 청크 병합 로직
└── 클라우드 연동: Google Drive API v3, Naver Cloud API

2.3 인프라

서버: XAMPP / Node.js 독립 실행
DB: SQLite (단일 파일 → 백업 용이)
파일: /data/files/{userId}/{year}/{month}/
설정: .env 파일 기반

3. UI 레이아웃 구조

3.1 메인 3단 레이아웃

┌─────────────────────────────────────────────────────────────────┐
│ HEADER: 로고 · 검색바 · 계정정보(쿼터) · 다크/라이트 토글 · 로그인 │
├──────────────┬──────────────────────────────┬───────────────────┤
│ LEFT PANEL │ CENTER (메인뷰) │ RIGHT PANEL │
│ 220px │ flex: 1 (전체 화면) │ 220px │
│ │ │ │
│ 썸네일 목록 │ ┌─────────────────────────┐ │ 카테고리 목록 │
│ (12개, 최신순)│ │ 제목 │ │ (계정관리자 무제한) │
│ │ │ 메타정보 (날짜·카테고리) │ │ │
│ [카테고리명] │ │ │ │ 전체 검색 │
│ [썸네일] │ │ 유튜브/쇼츠 임베드 │ │ │
│ [제목] │ │ │ │ 태그 목록 │
│ [내용 일부] │ │ 본문 내용 │ │ (박스형 20개) │
│ │ │ │ │ │
│ (스크롤) │ │ 파일 첨부 목록 │ │ 라이브러리 미리보기 │
│ │ │ │ │ (이미지 2열 3줄) │
│ │ │ 공유 버튼 │ │ │
│ │ │ 이전글 / 다음글 │ │ [라이브러리 →] │
│ │ │ 댓글 · 답변 │ │ │
│ │ └─────────────────────────┘ │ │
└──────────────┴──────────────────────────────┴───────────────────┘

3.2 반응형 브레이크포인트

구간 레이아웃
≥ 1280px 3단 (좌220 · 중앙flex · 우220)
768px ~ 1279px 2단 (좌목록 접힘 · 중앙 · 우패널)
< 768px 1단 (모바일: 목록 → 상세 → 에디터 순차)

3.3 모바일 네비게이션

하단 탭바 (모바일 전용)
[홈] [목록] [글쓰기] [라이브러리] [설정]

4. 핵심 기능 명세

4.1 게시글 (Note)

목록 화면 (Left Panel)

  • 최신 등록 순 12개, 무한 스크롤
  • 썸네일: 첫 번째 이미지 첨부 또는 카테고리 아이콘 자동 적용
  • 표시 정보: 카테고리명 · 제목 · 내용 앞 60자 · 날짜
  • 클릭 → 중앙 상세보기 즉시 로드 (SPA, 페이지 전환 없음)

상세 화면 (Center)

[제목]
[카테고리] [날짜] [작성자] [조회수]
[유튜브 또는 쇼츠 임베드] ← 링크 입력시 자동 표시
[본문 렌더링]
[첨부파일 목록]
- 이미지: 썸네일 클릭 → 슬라이드 뷰어
- PDF: 클릭 → 이북뷰어 (모달 또는 새 탭)
- 오디오: 인라인 플레이어 렌더링
- 기타: 다운로드 링크
[공유] [수정] [삭제]
[← 이전글] [다음글 →]
[댓글 목록]
└ [답변 입력]

편집 화면

[카테고리 선택 드롭다운]
[제목 입력]
[TipTap 웹에디터]
- 텍스트 서식 (볼드·이탤릭·취소선·코드)
- 제목 H1~H3
- 표 삽입
- 이미지 삽입 (드래그 앤 드롭)
- 체크박스 / 할 일 목록
- 코드 블록 (하이라이팅)
- 구분선
[태그 입력] (엔터로 추가, X로 삭제)
[유튜브/쇼츠 링크 입력]
[파일 첨부 영역]
- + 버튼으로 개수 무제한 추가
- 파일당 최대 100MB (청크 업로드)
- 업로드 진행바 개별 표시
- 첨부된 파일 목록 + 삭제 버튼
[임시저장] [발행]

4.2 라이브러리

라이브러리 메인 화면

┌─────────────────────────────────────────────────────┐
│ [이미지] [PDF] [오디오] [동영상] [기타] ← 탭 필터 │
├─────────────────────────────────────────────────────┤
│ │
│ 이미지 탭: │
│ [→ 슬라이드쇼로 보기] 버튼 │
│ 썸네일 3열 그리드, 클릭 → 라이트박스 │
│ │
│ PDF 탭: │
│ [→ 이북뷰어로 보기] 버튼 │
│ PDF 목록 (파일명·크기·등록일) │
│ │
│ 오디오 탭: │
│ [→ 오디오 플레이어] 버튼 │
│ 트랙 목록 (아티스트·제목·길이) │
│ │
└─────────────────────────────────────────────────────┘

이북뷰어 (PDF Viewer)

  • PDF.js 기반 페이지 렌더링
  • 좌우 페이지 넘기기 (book flip 애니메이션)
  • 썸네일 사이드바, 페이지 점프
  • 외부 공유 링크 생성:  /viewer/ebook/{token}  → 외부 사이트 임베드 가능
  • 임베드 코드 생성:  <iframe src="...">  복사 버튼

오디오 플레이어

  • 폴더/카테고리 기준 플레이리스트 자동 구성
  • 재생·정지·다음·이전·셔플·반복
  • 배경 재생 (페이지 이동해도 유지)
  • 트랙 커버 이미지 (없으면 기본 아이콘)

이미지 슬라이드쇼

  • Swiper.js 풀스크린 슬라이드
  • 자동재생 · 슬라이드 간격 설정
  • 공유 링크 생성: 슬라이드쇼 단독 URL 공유 가능

4.3 파일 업로드 시스템 (100MB 청크)

[클라이언트]
파일 선택
→ 5MB 단위 청크 분할
→ 청크 순서대로 POST /api/upload/chunk
→ 진행률 표시 (청크 단위)
→ 마지막 청크 → POST /api/upload/merge
→ 서버 응답: 파일 URL + 메타데이터
[서버]
청크 임시 저장: /data/tmp/{uploadId}/chunk_001 ...
병합 완료 → /data/files/{userId}/{year}/{month}/{uuid}.ext
썸네일 자동 생성 (이미지·PDF)
DB 파일 레코드 저장

4.4 클라우드 연동

구글 드라이브 연동

  • OAuth2 인증 후 드라이브 파일 목록 탐색
  • 드라이브 파일 → xNote 첨부파일로 가져오기 (복사 저장)
  • xNote 파일 → 드라이브로 내보내기

네이버 클라우드 연동

  • 네이버 클라우드 API 연동
  • 폴더 구조 탐색 + 파일 가져오기/내보내기

4.5 사용자 및 권한 관리

역할 (Role)

역할 권한
admin 모든 기능 + 카테고리 무제한 추가 + 사용자 관리 + 쿼터 설정
editor 글쓰기·수정·삭제(본인글) + 파일 업로드
viewer 읽기 + 댓글
guest 공개 게시물 읽기만

쿼터 관리

  • 사용자별 저장 용량 상한 설정 (관리자 지정)
  • 헤더에 사용량 표시:  사용중 1.2GB / 10GB
  • 쿼터 초과시 업로드 차단 + 경고 메시지

JWT 인증

Access Token: 15분 만료
Refresh Token: 30일 만료 (HttpOnly Cookie)
자동 갱신: axios 인터셉터로 무중단 처리

4.6 검색

  • 전문 검색 (제목 + 본문 + 태그 + 파일명)
  • SQLite FTS5 (Full-Text Search) 활용
  • 카테고리 필터 + 날짜 범위 필터
  • 태그 클릭 → 해당 태그 게시물 목록

4.7 댓글 시스템

  • 1단계 답변 (댓글 → 답변, 대댓글 없음)
  • 마크다운 경량 지원 (볼드·이탤릭·코드)
  • 작성자 수정·삭제 + 관리자 삭제

5. DB 스키마

-- 사용자
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
role TEXT DEFAULT 'editor', -- admin/editor/viewer/guest
quota_mb INTEGER DEFAULT 1024, -- 사용 가능 용량 (MB)
used_mb REAL DEFAULT 0,
theme TEXT DEFAULT 'dark',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 카테고리
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
parent_id INTEGER REFERENCES categories(id),
sort_order INTEGER DEFAULT 0,
created_by INTEGER REFERENCES users(id)
);
-- 게시글
CREATE TABLE notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT, -- HTML (TipTap 출력)
category_id INTEGER REFERENCES categories(id),
author_id INTEGER REFERENCES users(id),
youtube_url TEXT,
status TEXT DEFAULT 'published', -- draft/published
view_count INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 태그
CREATE TABLE tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE note_tags (
note_id INTEGER REFERENCES notes(id) ON DELETE CASCADE,
tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (note_id, tag_id)
);
-- 첨부파일
CREATE TABLE files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
note_id INTEGER REFERENCES notes(id) ON DELETE CASCADE,
uploader_id INTEGER REFERENCES users(id),
original_name TEXT NOT NULL,
stored_name TEXT NOT NULL,
file_path TEXT NOT NULL,
file_type TEXT, -- image/pdf/audio/video/other
mime_type TEXT,
size_bytes INTEGER,
thumbnail_path TEXT,
share_token TEXT UNIQUE, -- 이북뷰어 등 외부 공유용
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 댓글
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
note_id INTEGER REFERENCES notes(id) ON DELETE CASCADE,
parent_id INTEGER REFERENCES comments(id),
author_id INTEGER REFERENCES users(id),
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- FTS 검색 인덱스
CREATE VIRTUAL TABLE notes_fts USING fts5(
title, content, tokenize='unicode61'
);

6. API 설계

6.1 인증

Method Path 설명
POST /api/auth/login 로그인 (JWT 발급)
POST /api/auth/logout 로그아웃
POST /api/auth/refresh 토큰 갱신
GET /api/auth/me 내 정보 조회

6.2 게시글

Method Path 설명
GET /api/notes 목록 (페이지네이션·필터)
GET /api/notes/:id 상세 조회
POST /api/notes 생성
PUT /api/notes/:id 수정
DELETE /api/notes/:id 삭제
GET /api/notes/search 전문 검색

6.3 파일

Method Path 설명
POST /api/upload/chunk 청크 업로드
POST /api/upload/merge 청크 병합 완료
GET /api/files/:id 파일 다운로드
DELETE /api/files/:id 파일 삭제
POST /api/files/:id/share 공유 토큰 생성

6.4 라이브러리

Method Path 설명
GET /api/library 파일 타입별 목록
GET /api/library/images 이미지 목록
GET /api/library/pdf PDF 목록
GET /api/library/audio 오디오 목록

6.5 공개 뷰어 (비인증)

Method Path 설명
GET /viewer/ebook/:token 이북뷰어 공개 접근
GET /viewer/slideshow/:token 슬라이드쇼 공개 접근
GET /api/public/file/:token 공개 파일 스트리밍

7. 테마 시스템

/* 다크모드 (기본) */
:root[data-theme="dark"] {
--bg-primary: #0f0f0f;
--bg-secondary: #1a1a1a;
--bg-panel: #141414;
--text-primary: #e8e8e8;
--text-secondary: #999;
--border: #2a2a2a;
--accent: #4f9cf9;
--accent-hover: #3d85e0;
}
/* 라이트모드 */
:root[data-theme="light"] {
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--bg-panel: #fafafa;
--text-primary: #1a1a1a;
--text-secondary: #666;
--border: #e0e0e0;
--accent: #2563eb;
--accent-hover: #1d4ed8;
}

8. 개발 Phase 계획

Phase 1 — 코어 (4주)

  • 미완료프로젝트 세팅 (Vue3 + Express + SQLite)
  • 미완료JWT 인증 (로그인·로그아웃·갱신)
  • 미완료카테고리 CRUD
  • 미완료게시글 CRUD (TipTap 에디터 통합)
  • 미완료기본 파일 첨부 (5MB 이하 단순 업로드)
  • 미완료3단 레이아웃 + 다크/라이트 테마

Phase 2 — 파일 특화 (3주)

  • 미완료청크 업로드 (100MB)
  • 미완료이미지 슬라이드쇼 뷰어
  • 미완료PDF 이북뷰어 (PDF.js)
  • 미완료오디오 플레이어 (Howler.js)
  • 미완료라이브러리 화면

Phase 3 — 공유 & 검색 (2주)

  • 미완료SQLite FTS5 전문 검색
  • 미완료태그 시스템
  • 미완료공유 토큰 + 외부 임베드 URL
  • 미완료댓글·답변 시스템
  • 미완료이전글/다음글 네비게이션

Phase 4 — 다중 사용자 & 클라우드 (2주)

  • 미완료사용자 관리 (역할·쿼터)
  • 미완료관리자 대시보드
  • 미완료구글 드라이브 연동
  • 미완료네이버 클라우드 연동
  • 미완료모바일 최적화 완성

Phase 5 — 배포 & 완성 (1주)

  • 미완료보안 점검 (XSS·SQL Injection·파일 업로드 검증)
  • 미완료성능 최적화 (이미지 레이지 로딩·페이지네이션)
  • 미완료설치 가이드 (XAMPP / VPS / Synology)
  • 미완료백업·복원 스크립트

9. 보안 고려사항

항목 대책
파일 업로드 MIME 타입 검증 + 확장자 화이트리스트 + 실행파일 차단
XSS TipTap 출력 → DOMPurify 새니타이징
인증 JWT + HttpOnly Cookie + CSRF 토큰
파일 접근 DB 토큰 기반 접근 제어 (직접 경로 노출 금지)
쿼터 업로드 전 용량 사전 검증
SQL Prepared Statement 전용 사용

10. 설치 구조

xnote/
├── client/ # Vue 3 앱
│ ├── src/
│ │ ├── views/ # Home, Note, Editor, Library, Viewer
│ │ ├── components/
│ │ ├── stores/ # Pinia
│ │ └── api/ # axios 래퍼
│ └── dist/ # 빌드 결과물
├── server/ # Express API
│ ├── routes/
│ ├── middleware/
│ ├── models/
│ └── utils/
├── data/
│ ├── files/ # 업로드된 파일
│ ├── tmp/ # 청크 임시 저장
│ └── xnote.db # SQLite DB
├── .env
└── package.json

xNote v1.0 명세서 끝 — Phase 1 착수 시 이 문서를 기준으로 세부 태스크 분해 진행