309 lines
29 KiB
Markdown
309 lines
29 KiB
Markdown
# 파일-화면 매핑
|
|
|
|
> 현재 문서는 구현 예정 파일 기준 매핑이다. 실제 파일이 생성되면 경로와 화면 연결을 즉시 갱신한다.
|
|
|
|
## 레이아웃
|
|
|
|
| 파일 | 화면 |
|
|
|------|------|
|
|
| layouts/default.vue | 메인·목록·태그 — 3열 `gap`+중앙 `1fr`, `site-main` `max-w-[720px]`, 모바일 슬라이드 메뉴 |
|
|
| layouts/post.vue | 개별 게시물 — `default`와 동일 |
|
|
| layouts/admin.vue | 관리자 전체, 320px 밝은 Ghost형 사이드바(대시보드 `/admin` 활성 링크·사이트 보기 새 창·콘텐츠 구간 여백), 우측 전체 높이 캔버스, 멤버 수 표시, 하단 사용자 드롭다운·설정, `내 프로필` 멤버 편집 이동, 게시글 `+` 새 글 진입, 글 작성/수정 화면의 전체 화면 편집 모드와 문서 스크롤 잠금, **`/admin/settings`에서는 사이드바 숨김·본문 전체 화면·설정용 문서 스크롤 잠금** |
|
|
| layouts/page.vue | 고정 페이지 전체 화면 |
|
|
| app.vue | 공개 사이트 설정 기반 파비콘 head 링크와 기본 title template |
|
|
|
|
## Composables
|
|
|
|
| 파일 | 용도 |
|
|
|------|------|
|
|
| composables/formatPostDate.js | 공개 게시일 `YYYY.MM.DD`, 관리자·수정일 보조 `formatPostDateTime`, `wasPostUpdatedAfterPublish` |
|
|
| composables/createPostSummary.js | 게시물 요약·본문에서 목록·SEO용 짧은 설명 텍스트 생성 |
|
|
| composables/useAdminToast.js | 관리자 우측 상단 토스트(성공·오류·안내; 모달보다 위 z-index) |
|
|
|
|
## 공유 라이브러리(서버·클라이언트 공통)
|
|
|
|
| 파일 | 용도 |
|
|
|------|------|
|
|
| lib/upload-size-limit.js | 관리자 미디어 업로드 종류별 최대 바이트 판별·용량 문구(서버·클라이언트 공용) |
|
|
| lib/external-favicon-url.js | 외부 URL 호스트 기준 Google `s2/favicons` 썸네일 URL 생성(내부 경로는 빈 문자열) |
|
|
| lib/navigation-editor-tree.js | 관리자 메뉴 UI·서버 `renumberSortOrderByTree`가 쓰는 `buildNavigationEditorTree`, 관리자 상단 네비 평면 표용 `flattenNavigationEditorWrappers` |
|
|
| lib/markdown-content-normalizer.js | 관리자 Markdown-first 전환 후 레거시 블록 배열·객체 본문 값을 저장용 마크다운 문자열로 변환 |
|
|
| lib/markdown-block-context.js | 관리자 Markdown textarea 커서 위치 기준 이미지·갤러리·임베드 블록 설정 패널 대상 판별 |
|
|
| lib/markdown-image.js | 이미지 마크다운 직렬화·파싱, 단독 이미지 URL 판별 |
|
|
| lib/markdown-slash-commands.js | 관리자 Markdown-first 에디터 슬래시 명령 목록과 삽입 줄 정의 |
|
|
| lib/analytics-shared.js | 통계 추적 경로 필터·체류/스크롤 상수(클라이언트·서버 공용) |
|
|
| lib/analytics.js | 서버 전용 visitor/session hash(`node:crypto`) |
|
|
|
|
## Nuxt 모듈
|
|
|
|
| 파일 | 용도 |
|
|
|------|------|
|
|
| modules/nuxt-ssr-paths-write.mjs | `paths.mjs`를 `.nuxt`에 기록해 Node가 `#internal/nuxt/paths`를 해석할 수 있게 함 |
|
|
|
|
## Scripts
|
|
|
|
| 파일 | 용도 |
|
|
|------|------|
|
|
| scripts/check-js-syntax.js | `npm run lint`에서 JS/MJS/CJS 파일을 `node --check`로 문법 점검 |
|
|
|
|
## 서버 미들웨어
|
|
|
|
| 파일 | 용도 |
|
|
|------|------|
|
|
| server/middleware/admin-api-session.js | `/admin/api/*` 요청마다 관리자 세션과 현재 DB 권한(`owner`/`admin`) 재확인 |
|
|
| server/routes/uploads/[...path].get.js | 런타임 업로드 파일 제공 API(`/app/public/uploads` 볼륨 파일을 `/uploads/**`로 스트리밍) |
|
|
|
|
## 사이트 컴포넌트
|
|
|
|
| 파일 | 화면 위치 |
|
|
|------|-----------|
|
|
| components/auth/AuthPasswordVisibilityToggle.vue | 로그인·회원가입 비밀번호 표시/숨김 토글(SVG, scoped 스타일·`field-name`으로 접근성 레이블 구분) |
|
|
| components/site/SiteTopChrome.vue | 공개 레이아웃 상단 고정 영역(어나운스 바+헤더), `--site-top-chrome-height` CSS 변수 |
|
|
| components/site/SiteAnnouncementBar.vue | 공개 사이트 상단 어나운스 배너(문구·선택 링크·배경색·닫기) |
|
|
| components/site/SiteHeader.vue | 모든 공개 페이지 상단, 사이트 이름 텍스트 브랜드, `grid-cols-3`로 검색 패널 중앙 정렬(`md+`), 우측 사용자 아바타 드롭다운, `/`·`SiteSearchModal` |
|
|
| components/site/SiteSearchModal.vue | `Teleport`·전체 화면 딤·Tags/Posts 결과·일치 구간 강조, 열림 시 `html.site-search-open` 스크롤 잠금 |
|
|
| components/site/LeftSidebar.vue | 왼쪽 사이드바, `lg+`는 `sticky`+고정 높이+내부 무스크롤바 스크롤, `lg` 미만은 고정 슬라이드 패널, 상단 메뉴는 `SidebarPrimaryNavList`+`provide`로 트리·펼침 상태(`sori-primary-nav-expanded`), Authors 영역은 비공개, 푸터 `footer` 링크는 `flex-wrap`·테마 버튼 `shrink-0`, 태그 카테고리·테마 점은 `site-sidebar-nav-row` 호버 |
|
|
| components/site/SidebarPrimaryNavList.vue | 상단 네비: 부모·리프 동일 `before` 막대/호버 원형, 내부 현재 경로 `--site-accent`, 행 `w-full`+`site-sidebar-nav-row` 호버(`#F7F4EF` 라이트), `inject`·`localStorage` 펼침 |
|
|
| components/site/RightSidebar.vue | 오른쪽 사이드바, 공개 `GET /api/navigation`의 `recommended` 카드 목록(외부 URL은 Google 파비콘 프록시 썸네일), Follow·구독 폼, About 영역은 비공개, `lg+` 스티키 |
|
|
| components/site/MainColumn.vue | 메인 화면 중앙, `lg:max-w-[720px]`로 본문 상한 |
|
|
| components/site/HomeHero.vue | 홈 상단 720px 커버 배너, 라이트·다크 테마별 이미지 교체, 왼쪽 하단 오버레이 제목·본문 |
|
|
| components/site/PostCard.vue | 목록의 게시물 카드, 카드 hover 인터랙션, 태그는 있을 때만 메타에 표시 |
|
|
| components/site/PostCardMedia.vue | 게시물 카드 썸네일(대표 이미지 없으면 제목 텍스트 플레이스홀더) |
|
|
| components/site/TagHeader.vue | 태그 페이지 헤더 |
|
|
| components/comments/PostComments.vue | 게시물 상세 `#comments` 영역, 회원 댓글/답글(1단) 작성 및 목록 표시, 작성자 썸네일/좋아요/상대시간 표시 |
|
|
|
|
## 관리자 컴포넌트
|
|
|
|
| 파일 | 화면 위치 |
|
|
|------|-----------|
|
|
| components/admin/AdminSettingsNavIcon.vue | 사이트 설정 좌측 내비 항목 아이콘(`iconId`별 SVG·미구현 placeholder) |
|
|
| components/admin/AdminMediaVideoThumbnail.vue | 관리자 미디어 목록 비디오 항목의 초반 프레임 캔버스 썸네일 |
|
|
| components/admin/AdminPostForm.vue | 관리자 글 작성/수정 폼, Ghost형 툴바(영문 상태·Publish/Update/Unpublish/Unschedule, 서버 반영 상태 기준 분기), 초안만 서버 디바운스 자동 저장·신규 임시 슬러그·발행·예약 글은 Update로만 반영, 발행 모달(중앙 배치), 좌우 설정 패널, 미리보기 emit·미저장 이탈 가드, 추천 글 토글, 태그 색상 배지 다중 입력·메인 태그 드롭다운·부분 검색 추천 |
|
|
| components/admin/AdminPageForm.vue | 관리자 페이지 작성/수정 폼, 대표 이미지 선택 |
|
|
| components/admin/AdminMarkdownEditor.vue | 관리자 글 Markdown-first 에디터, 라이브·소스 모드 `/` 슬래시 명령·미디어 모달(이미지·갤러리·비디오·오디오·파일), 커서 블록 컨텍스트·`block-panel` emit, 라이브 이미지 설정 패널·이미지↔갤러리 드래그 변환(`merge-images-to-gallery`·`insert-image-to-gallery`·`extract-gallery-image`), 블록 패널 바깥 클릭 닫기·미디어 모달 중 유지, 소스 모드 wrap 라인 번호 보정·라이브↔소스 위치 복원 |
|
|
| components/admin/AdminEditorBlockPanel.vue | 게시물 설정 사이드바 오버레이 블록 설정(이미지·갤러리·임베드), 갤러리 선택 이미지 강조 |
|
|
| components/admin/AdminBlockEditor.vue | 관리자 글 블록형 에디터, 이미지/갤러리/콜아웃/토글/임베드 블록, 콜아웃 Emoji on/off·이모지 프리셋·배경 프리셋 선택(우측 고정 설정 패널), 갤러리 복수 미디어 선택·이미지 수별 열 배치·삽입 위치 표시 드래그 순서 변경, 한글 조합 입력 처리, Shift+Enter 줄바꿈, 코드 블록 단축 변환, AFFiNE 참고 세로 막대형 블록 핸들 선택/삭제/드래그 이동과 삽입선 표시, 하단 빈 입력 블록 유지, 본문 placeholder 표시 |
|
|
| components/admin/AdminTagForm.vue | 관리자 태그 생성/수정 폼(이름/슬러그/설명/색상만 편집) |
|
|
| components/admin/AdminMemberForm.vue | 관리자 멤버 추가/수정 폼(Ghost형 3분할, 요약 1fr·입력 2fr, 원형 썸네일 hover 등록·변경·삭제, 기본 정보·레이블·관리자 노트·활동 요약, 설정 메뉴의 비밀번호 변경·멤버 삭제 모달, 미저장 변경사항 이탈 확인) |
|
|
| components/admin/AdminUnsavedChangesModal.vue | 관리자 편집 화면 공통 미저장 변경사항 이탈 확인 모달(상단 40px 위치) |
|
|
|
|
## 관리자 컴포저블
|
|
|
|
| 파일 | 화면 위치 |
|
|
|------|-----------|
|
|
| composables/useAdminUnsavedChangesGuard.js | 관리자 게시글/멤버 편집 화면 라우트 이탈 확인과 브라우저 `beforeunload` 연결 |
|
|
|
|
## 콘텐츠 컴포넌트
|
|
|
|
| 파일 | 화면 위치 |
|
|
|------|-----------|
|
|
| components/content/ContentRenderer.vue | 게시물/페이지 본문 |
|
|
| components/content/ContentMarkdownRenderer.vue | 마크다운 문자열 기반 본문 렌더링, 문단 text-base(16px), 빈 줄 spacer 보존·hard break `<br>` 처리, 확장 블록 파싱, 인용 배경 옵션(`> [!bg=...]`), 라이브 이미지·갤러리 드래그 병합·추가·분리 UI, 갤러리 비율 기반 행 레이아웃, 라이브 갤러리 개별 이미지 편집·삭제, 리스트 마커 파란 계열 통일 |
|
|
| components/content/ProseHeading.vue | h1~h6 제목, 기본 mt-12 제거 |
|
|
| components/content/ProseImage.vue | 본문 내 이미지, 로드 실패·빈 URL placeholder |
|
|
| components/content/ProseList.vue | 목록 |
|
|
| components/content/ProseBlockquote.vue | 인용구, 콜아웃과 같은 배경 프리셋, 다크모드 기본 인용 텍스트 가독성 보정 |
|
|
| components/content/ProseCodeBlock.vue | 코드 블록 공통 셸(다크 배경, 줄번호 gutter, 공개 복사 버튼) |
|
|
| components/content/ContentMarkdownCodeBlockEditor.vue | 라이브 모드 코드 블록 인라인 편집(Language·줄번호 토글) |
|
|
| components/content/ProseButton.vue | 버튼 |
|
|
| components/content/ProseCallout.vue | Callout 카드(Emoji 표시/숨김, 배경 프리셋, 상단 여백 중심) |
|
|
| components/content/ProseToggle.vue | Toggle 카드(펼침 애니메이션, chevron 트리거) |
|
|
| components/content/ContentMarkdownToggleEditor.vue | 라이브 모드 토글 제목·본문 인라인 편집 |
|
|
| components/content/ProseVideo.vue | `:::video` 공개 비디오 카드 |
|
|
| components/content/ProseAudio.vue | `:::audio` 공개 오디오 플레이어 카드 |
|
|
| components/content/ProseFile.vue | `:::file` 공개 다운로드 파일 카드 |
|
|
| components/content/ProseProduct.vue | 상품 카드 |
|
|
| components/content/ProseBookmark.vue | 본문 북마크 카드(썸네일·도메인·`http(s)` 외부 링크) |
|
|
| components/content/ProseSignup.vue | 본문 회원가입·뉴스레터 CTA 카드 |
|
|
| components/content/ProseHeaderCard.vue | 헤더 카드 |
|
|
| components/content/ProseEmbed.vue | YouTube 영상 iframe, X/Twitter 소셜 iframe, Mastodon `/embed` iframe, 기타 `http(s)` 외부 링크 |
|
|
|
|
## 관리자 페이지
|
|
|
|
| 파일 | 화면 |
|
|
|------|------|
|
|
| pages/admin/index.vue | 대시보드(상단 요약: 현재 접속자·오늘 접속자·게시물 수, 기간 선택형 방문자수·평균 체류·50% 스크롤 차트, 접속자 목록, 인기 게시물 참여 지표) |
|
|
| pages/admin/login.vue | 관리자 로그인, 일반 로그인과 같은 다크 인증 스타일·우측 배치 및 내부 오른쪽 정렬 폼, 이메일·비밀번호 모두 입력 시에만 제출 버튼 활성 |
|
|
| pages/admin/posts/index.vue | 글 목록, 헤더 우측에 필터(상태·태그·정렬)와 «새 글»을 한 줄 배치, 예약/초안/발행 텍스트 상태, 제목 옆 댓글 수, 첫 번째 태그 색상 대표 배지, 화면 기준 행 more vert 메뉴(추천·삭제) |
|
|
| pages/admin/posts/new.vue | 글 작성, Ghost 스타일 작성 폼, 초안 `POST` 디바운스 자동 저장·이탈 직전 플러시, 저장 토스트 |
|
|
| pages/admin/posts/[id].vue | 글 수정, `AdminPostForm`, 저장·초안 디바운스 자동 저장(`autoSaving`)·이탈 직전 플러시·삭제·토스트 |
|
|
| pages/admin/posts/preview.vue | 글 미리보기(공개 상세와 동일한 중앙 컬럼·수평 패딩) |
|
|
| pages/admin/pages/index.vue | 페이지 목록, 화면 기준 행 more vert 메뉴(수정·삭제) |
|
|
| pages/admin/pages/new.vue | 페이지 작성, 저장 토스트 |
|
|
| pages/admin/pages/[id].vue | 페이지 수정, 저장/삭제 토스트 |
|
|
| pages/admin/media/index.vue | 미디어 관리, **미디어 라이브러리/썸네일** 탭, 이미지·비디오·오디오·파일 종류 필터, 미사용 필터, 비디오 프레임 썸네일, 폴더 트리 more vert(폴더 삭제), 검색·드래그·상세 모달 등 |
|
|
| pages/admin/navigation/index.vue | 메뉴 관리: 상단/하단/추천 탭, 행 more vert(메뉴 항목 삭제), 드래그 정렬, `useAdminToast` |
|
|
| components/admin/AdminRowMoreMenu.vue | 관리자 행 more vert 메뉴(트리거·화면 기준 팝오버) |
|
|
| composables/useAdminRowMenu.js | 관리자 행 메뉴 열림 상태·바깥 클릭 닫기 |
|
|
| pages/admin/tags/index.vue | 태그 관리(메인 태그 드래그 정렬 자동 저장·more vert 메뉴, 일반 태그 배지 more vert 메뉴·검색/정렬, 태그 추가 버튼), 액션 피드백 토스트 |
|
|
| pages/admin/tags/new.vue | 태그 생성 |
|
|
| pages/admin/tags/[id].vue | 태그 수정 |
|
|
| pages/admin/settings/index.vue | 사이트 설정 Ghost형 전체 화면, **POST 설정**(`showPostUpdatedAt` 토글·읽기 모드 비활성 토글), 블로그 제목·설명·기타(로고·URL·저작권), **메인 화면**(라이트·다크 커버 이미지·오버레이 텍스트), **어나운스 바**(사용 토글·맞춤 설정·배경색), **스팸 필터**(가입 금지 닉네임), 타임존·Import/Export 플레이스홀더 |
|
|
| lib/signup-blocked-usernames.js | 가입 금지 닉네임 정리·매칭·안내 문구 |
|
|
| pages/admin/members/index.vue | 관리자 멤버 목록(Ghost형 테이블, 검색, 조건 필터, 멤버 추가 버튼, 닉네임+이메일, 가입일+최근 활동, IP, 댓글 수, 활동 상태 텍스트) |
|
|
| pages/admin/members/new.vue | 관리자 멤버 추가(썸네일 URL, 이름, 이메일, 레이블, 관리자 노트) |
|
|
| pages/admin/members/[id].vue | 관리자 멤버 상세/수정(회원 요약, 가입 정보, 활동 요약, 기본 정보 저장, 삭제 후 목록 이동) |
|
|
|
|
## 공개 페이지
|
|
|
|
| 파일 | 화면 |
|
|
|------|------|
|
|
| pages/index.vue | 홈, `site_settings` 커버가 있을 때만 라이트·다크 이미지 지원 `HomeHero`, Featured/Latest, Latest 피드 Compact 기본값·List·Cards 보기, Latest 메타는 태그가 있을 때만 태그 배지 표시, Featured는 추천 글이 있을 때만 표시하며 이미지 없는 추천 글은 제목 placeholder 썸네일과 모바일 터치 가로 스크롤·스냅, 끝에서 화살표 비활성 |
|
|
| pages/posts/index.vue | 게시물 전체 목록, 태그는 있을 때만 카드 메타에 표시 |
|
|
| pages/posts/[slug].vue | `/post/:slug` 리다이렉트 |
|
|
| pages/post/[slug].vue | 블로그 글 상세, 첫 태그가 있을 때만 메타 행에 태그 링크, 로그인 회원이 글쓴이(`author_id`)이면 공유 버튼 옆 새 탭 편집 링크 표시, 게시물 SEO/OG 메타 출력(요약 없으면 본문 fallback), 공유 모달(X/Bluesky/Facebook/LinkedIn/Email/링크복사), 회원 댓글 섹션 |
|
|
| pages/tags/index.vue | 태그 전체 목록, 중앙 히어로와 3열 태그 카드, 좌측 컬러 보더/hover 오버레이 |
|
|
| pages/tags/[slug].vue | `/tag/:slug` 리다이렉트 |
|
|
| pages/tag/[slug].vue | 태그별 글 목록, 상단 태그 헤더 + 공통 섹션 패딩을 쓰는 리스트형 게시물 카드 |
|
|
| pages/pages/[slug].vue | 고정 페이지 상세 |
|
|
| pages/signup.vue | 회원가입 3단계, `emailOtpConfigured`일 때 이메일 OTP·인증번호 받기, `POST /api/auth/email-otp/request` |
|
|
| pages/signin.vue | 로그인, `/forgot-password` 링크 |
|
|
| pages/forgot-password.vue | 비밀번호 찾기(Resend 설정 시 OTP 발송·`POST /api/auth/password-reset/confirm`) |
|
|
| pages/settings/index.vue | 회원 설정(상단 프로필 요약, 가입 정보, 댓글 참여도, 하단 프로필 입력·이전 로그인 활동, 썸네일 변경·제거, 닉네임 저장, 설정 메뉴 모달 비밀번호 변경·회원 탈퇴) |
|
|
|
|
## 서버 API
|
|
|
|
| 파일 | 기능 |
|
|
|------|------|
|
|
| server/api/posts.get.js | 게시물 목록 샘플 API |
|
|
| server/api/posts/[slug].get.js | 게시물 상세 샘플 API |
|
|
| server/api/pages.get.js | 고정 페이지 목록 샘플 API |
|
|
| server/api/pages/[slug].get.js | 고정 페이지 상세 샘플 API |
|
|
| server/api/tags.get.js | 태그 목록 샘플 API |
|
|
| server/api/search.get.js | 통합 검색 API(`q` 쿼리) |
|
|
| server/api/site-settings.get.js | 공개 사이트 설정 API |
|
|
| server/api/navigation.get.js | 공개 네비게이션 API |
|
|
| server/api/auth/signup.post.js | 회원 가입 API(선택 `emailOtp`, Resend 설정 시 일반 가입에 필수) |
|
|
| server/api/auth/bootstrap-status.get.js | 최초 관리자 여부 + `emailOtpConfigured` |
|
|
| server/api/auth/email-otp/request.post.js | Resend로 OTP 발송(`signup` / `password_reset`), 발송 실패 챌린지 삭제 |
|
|
| server/api/auth/password-reset/confirm.post.js | OTP 검증 후 비밀번호 재설정 |
|
|
| server/repositories/email-otp-repository.js | `email_otp_challenges` CRUD·검증 |
|
|
| server/utils/email-otp.js | OTP 생성·해시 |
|
|
| server/utils/resend-mail.js | Resend REST 발송 |
|
|
| server/api/auth/login.post.js | 회원 로그인 API |
|
|
| server/api/auth/me.get.js | 회원 세션 조회 API(`isAdmin`, `role` 포함) |
|
|
| server/api/auth/logout.post.js | 회원 로그아웃 API |
|
|
| server/api/auth/profile.get.js | 회원 프로필 조회 API |
|
|
| server/api/auth/profile.put.js | 회원 프로필 수정 API(닉네임·`avatarUrl`; 관리 썸네일 URL 교체 시 메타만 분리) |
|
|
| server/api/auth/avatar.post.js | 회원 썸네일 업로드 API(WebP 변환, 최소 해상도 검증, 중앙 1:1 강제 크롭, 품질 보정, `media_metadata` 논리 폴더 `썸네일`) |
|
|
| server/api/auth/avatar.delete.js | 회원 썸네일 삭제 API |
|
|
| server/api/auth/check-username.get.js | 닉네임 중복 확인 API |
|
|
| server/api/auth/password.put.js | 회원 비밀번호 변경 API |
|
|
| server/api/auth/account.delete.js | 회원 탈퇴 API(마지막 `owner` 보호, 관리자 세션 함께 정리) |
|
|
| server/api/posts/[slug]/comments.get.js | 게시물 댓글 목록 조회 API |
|
|
| server/api/posts/[slug]/comments.post.js | 게시물 댓글 작성 API |
|
|
| server/api/posts/[slug]/comments/[commentId]/like.post.js | 댓글 좋아요 토글 API |
|
|
| server/routes/admin/api/auth/login.post.js | 관리자 로그인 API |
|
|
| server/routes/admin/api/auth/logout.post.js | 관리자 로그아웃 API |
|
|
| server/routes/admin/api/auth/me.get.js | 관리자 세션 조회 API |
|
|
| server/routes/admin/api/posts.get.js | 관리자 게시물 목록 API |
|
|
| server/routes/admin/api/posts.post.js | 관리자 게시물 생성 API |
|
|
| server/routes/admin/api/posts/[id].get.js | 관리자 게시물 상세 API |
|
|
| server/routes/admin/api/posts/[id].put.js | 관리자 게시물 수정 API |
|
|
| server/routes/admin/api/posts/[id].delete.js | 관리자 게시물 삭제 API |
|
|
| server/routes/admin/api/pages.get.js | 관리자 고정 페이지 목록 API |
|
|
| server/routes/admin/api/pages.post.js | 관리자 고정 페이지 생성 API |
|
|
| server/routes/admin/api/pages/[id].get.js | 관리자 고정 페이지 상세 API |
|
|
| server/routes/admin/api/pages/[id].put.js | 관리자 고정 페이지 수정 API |
|
|
| server/routes/admin/api/pages/[id].delete.js | 관리자 고정 페이지 삭제 API |
|
|
| server/routes/admin/api/media.get.js | 관리자 미디어 목록 API |
|
|
| server/routes/admin/api/media.put.js | 관리자 미디어 파일명 변경 및 단일/복수 폴더 변경 API |
|
|
| server/routes/admin/api/media.delete.js | 관리자 미디어 삭제 API |
|
|
| server/routes/admin/api/media-folders.get.js | 관리자 미디어 폴더 목록 API |
|
|
| server/routes/admin/api/media-folders.post.js | 관리자 미디어 폴더 생성 API |
|
|
| server/routes/admin/api/uploads.post.js | 관리자 게시물·페이지용 미디어 업로드 API(이미지·비디오·오디오·문서, 원본명 기반 파일명·충돌 시 넘버링, `/uploads/posts` 저장, 성공 시 `media_metadata`를 `미분류`로 기록) |
|
|
| server/routes/admin/api/member-avatar.post.js | 관리자 새 회원 생성 전 썸네일 사전 업로드 API(`/uploads/members/avatars` 저장, WebP 변환·1:1 크롭) |
|
|
| server/routes/admin/api/tags.get.js | 관리자 태그 목록 API(`tagType`, `q`, `limit` 검색 옵션) |
|
|
| server/routes/admin/api/tags.post.js | 관리자 태그 생성 API |
|
|
| server/routes/admin/api/tags/[id].get.js | 관리자 태그 상세 API |
|
|
| server/routes/admin/api/tags/[id].put.js | 관리자 태그 수정 API |
|
|
| server/routes/admin/api/tags/[id].delete.js | 관리자 태그 삭제 API |
|
|
| server/routes/admin/api/tags/reorder.put.js | 관리자 메인 태그 순서 일괄 저장 API |
|
|
| server/routes/admin/api/settings.get.js | 관리자 사이트 설정 조회 API |
|
|
| server/routes/admin/api/settings.put.js | 관리자 사이트 설정 수정 API |
|
|
| server/routes/admin/api/settings/logo.post.js | 관리자 사이트 로고 업로드 API(`/uploads/system/logo-YYYYMM-*.webp`, `/uploads/system/favicon-YYYYMM-*.png` 생성, `시스템` 미디어 메타 저장, DB 반영 없이 URL 반환) |
|
|
| server/routes/admin/api/settings/home-cover.post.js | 관리자 메인 화면 커버 업로드 API(`/uploads/system/home-cover-YYYYMM-*.webp` 생성, `시스템` 미디어 메타 저장, 라이트·다크 슬롯용 URL 반환) |
|
|
| server/routes/admin/api/navigation.get.js | 관리자 네비게이션 목록 API |
|
|
| server/routes/admin/api/navigation.put.js | 관리자 네비게이션 일괄 저장 API |
|
|
| server/routes/admin/api/members.get.js | 관리자 멤버 목록 API |
|
|
| server/routes/admin/api/members.post.js | 관리자 멤버 생성 API |
|
|
| server/routes/admin/api/members/[id].get.js | 관리자 멤버 상세 API |
|
|
| server/routes/admin/api/members/[id].put.js | 관리자 멤버 기본 정보 수정 API(회원 전용 썸네일 교체·제거 시 메타 연결 분리) |
|
|
| server/routes/admin/api/members/[id]/avatar.post.js | 관리자 멤버 썸네일 업로드 및 즉시 반영 API |
|
|
| server/routes/admin/api/members/[id]/role.put.js | 관리자 멤버 권한 변경 API |
|
|
| server/utils/content-schema.js | Zod 콘텐츠 스키마 |
|
|
| server/utils/sample-content.js | 샘플 콘텐츠 저장소 |
|
|
| server/utils/admin-auth.js | 관리자 세션 쿠키 인증 유틸리티 |
|
|
| server/utils/member-auth.js | 회원 세션 쿠키 인증 유틸리티 |
|
|
| server/utils/member-avatar.js | 회원 전용 썸네일 경로 검증·프로필 분리 시 `media_metadata`만 제거(디스크는 관리자 미디어에서 정리) |
|
|
| server/utils/member-avatar-upload.js | 회원 썸네일 공통 업로드 검증·WebP 변환·중앙 1:1 크롭·저장 유틸 |
|
|
| server/utils/admin-post-input.js | 관리자 게시물 입력값 검증 스키마 |
|
|
| server/utils/admin-page-input.js | 관리자 고정 페이지 입력값 검증 스키마 |
|
|
| server/utils/admin-site-settings-input.js | 관리자 사이트 설정 입력값 검증 스키마 |
|
|
| server/utils/admin-navigation-input.js | 관리자 네비게이션 입력값 검증 스키마 |
|
|
| server/utils/admin-tag-input.js | 관리자 태그 입력값 검증 스키마 |
|
|
| server/utils/site-settings.js | 사이트 설정 기본값 유틸리티 |
|
|
| server/utils/navigation-items.js | DB 없을 때 기본 네비 항목(UUID id·parentId·isFolder) |
|
|
| server/utils/navigation-tree.js | 네비 검증·삽입 순서·공개 primary 트리·DFS sort_order 재부여 |
|
|
| server/utils/media-library.js | 업로드 미디어·논리 폴더(`미분류`, 예약 `썸네일`)·`avatarOwner` 부착·아바타 삭제/이름변경 차단 |
|
|
| server/repositories/postgres-client.js | PostgreSQL 클라이언트 |
|
|
| server/repositories/content-repository.js | 콘텐츠 조회 저장소 |
|
|
| server/repositories/member-repository.js | 회원 조회/생성 저장소 |
|
|
| server/repositories/comment-repository.js | 댓글 조회/생성 저장소 |
|
|
| server/repositories/analytics-repository.js | 방문·게시물 통계 집계·관리자 요약 조회·방문자 해시 보관 정리 |
|
|
| server/utils/analytics-pageview-input.js | `POST /api/analytics/pageview` 검증·기록 |
|
|
| server/api/analytics/pageview.post.js | 공개 통계 수집 API |
|
|
| server/api/analytics/heartbeat.post.js | 공개 heartbeat·체류·스크롤 수집 API |
|
|
| server/utils/analytics-heartbeat-input.js | heartbeat 검증·기록 |
|
|
| server/routes/admin/api/analytics/summary.get.js | 관리자 통계 요약 API |
|
|
| server/routes/admin/api/analytics/posts.get.js | 관리자 인기 게시물 API |
|
|
| server/routes/admin/api/analytics/realtime.get.js | 관리자 실시간 접속자 API |
|
|
| plugins/site-analytics.client.js | 공개 라우트 pageview·heartbeat·read 클라이언트 전송 |
|
|
|
|
## 데이터베이스
|
|
|
|
| 파일 | 기능 |
|
|
|------|------|
|
|
| db/migrations/001_initial_schema.sql | PostgreSQL 초기 테이블 스키마 |
|
|
| db/migrations/002_seed_development.sql | 개발용 샘플 데이터 |
|
|
| db/migrations/003_add_tag_display_fields.sql | 태그 표시 순서와 색상 필드 추가 |
|
|
| db/migrations/004_add_site_settings.sql | 사이트 설정 테이블 추가 |
|
|
| db/migrations/024_navigation_recommended_location.sql | `navigation_items.location`에 `recommended` 값 허용 |
|
|
| db/migrations/017_navigation_hierarchy.sql | `navigation_items`에 `parent_id`·`is_folder`, `(location,label,url)` 유니크 제거 |
|
|
| db/migrations/019_dedupe_navigation_items.sql | 반복 마이그레이션으로 생긴 네비게이션 중복 행 정리 및 중복 방지 인덱스 |
|
|
| db/migrations/005_add_navigation_items.sql | 네비게이션 항목 테이블 추가 |
|
|
| db/migrations/006_add_media_metadata.sql | 미디어 메타데이터 테이블 추가 |
|
|
| db/migrations/007_add_media_folders.sql | 미디어 폴더 테이블 추가 |
|
|
| db/migrations/016_media_category_normalize.sql | `media_metadata` 레거시 `posts`→`미분류`, `회원/썸네일`→`썸네일` 정리 |
|
|
| db/migrations/008_add_post_seo_fields.sql | 게시물 SEO 필드 추가 |
|
|
| db/migrations/009_add_post_og_image.sql | 게시물 OG 이미지 필드 추가 |
|
|
| db/migrations/010_add_members_and_comments.sql | 회원/댓글 테이블 추가 |
|
|
| db/migrations/011_add_member_profile_and_activity.sql | 회원 아바타/최근 활동 컬럼 추가 및 닉네임 유니크 인덱스 추가 |
|
|
| db/migrations/012_add_comment_likes.sql | 댓글 좋아요 테이블 추가 |
|
|
| db/migrations/014_add_user_role_levels.sql | 회원 권한 3단계(owner/admin/member) 컬럼 추가 |
|
|
| db/migrations/013_add_user_admin_role.sql | 회원 관리자 권한 컬럼 추가 및 첫 사용자 관리자 승격 |
|
|
| db/migrations/015_add_tag_type_and_reorder_support.sql | 태그 유형(`managed`/`general`) 컬럼 추가 |
|
|
| db/migrations/030_analytics_daily_stats.sql | 사이트·게시물 일별 통계·일별 방문자 해시 테이블 |
|
|
| db/migrations/031_analytics_engagement_and_realtime.sql | 체류·스크롤 집계 컬럼·실시간 접속 세션 테이블 |
|
|
| db/migrations/032_add_post_author.sql | 게시물 작성자(`posts.author_id`) 컬럼 추가 및 기존 글 owner/admin backfill |
|
|
| db/migrations/033_site_settings_home_cover_dark_image.sql | 사이트 설정 다크모드 홈 커버 이미지 URL 컬럼 추가 |
|
|
|
|
## 설정/배포
|
|
|
|
| 파일 | 기능 |
|
|
|------|------|
|
|
| package.json | Nuxt 실행 스크립트와 의존성 |
|
|
| nuxt.config.js | Nuxt 앱 설정, `tailwindcss.cssPath`로 `main.css` 단일 엔트리, Tailwind 모듈, 관리자 QA를 위한 개발 도구 비활성화, 회원 썸네일 최소/최대 해상도·품질 런타임 설정 |
|
|
| tailwind.config.js | Tailwind 테마 설정 |
|
|
| assets/css/main.css | 전역 스타일, 공개 배경·사이드바 배경 통일 기준, 관리자 라이트 테마 격리(`admin-layout`), 좌측 사이드바/그리드 전환 애니메이션, 네비게이션 세로 바 hover 효과 |
|
|
| composables/useMenuState.js | 좌측 메뉴 열림 상태·`closeMenu`(모바일 백드롭 등) |
|
|
| composables/useThemeMode.js | 사용자 화면 라이트/다크 테마 상태 관리 |
|
|
| middleware/admin-auth.global.js | 관리자 페이지 접근 인증 |
|
|
| scripts/dev-server.js | 로컬 개발 서버 링크 요약 출력 |
|
|
| scripts/migrate-database.js | 로컬·NAS DB 마이그레이션 적용/상태/baseline 실행 |
|
|
| scripts/migrate-development-db.js | 기존 로컬 개발 DB 마이그레이션 명령 호환 래퍼 |
|
|
| scripts/migrate-production-db.sh | npm 없는 NAS 호스트용 운영 DB 마이그레이션 적용/상태/baseline 실행 |
|
|
| .env.example | 환경 변수 예시 |
|
|
| Dockerfile | NAS 운영 이미지 빌드 |
|
|
| docker-compose.yml | NAS 컨테이너 실행 초안 |
|