# 파일-화면 매핑 > 현재 문서는 구현 예정 파일 기준 매핑이다. 실제 파일이 생성되면 경로와 화면 연결을 즉시 갱신한다. ## 레이아웃 | 파일 | 화면 | |------|------| | layouts/default.vue | 메인·목록·태그 — 3열 `gap`+중앙 `1fr`, `site-main` `max-w-[720px]`, 모바일 슬라이드 메뉴 | | layouts/post.vue | 개별 게시물 — `default`와 동일 | | layouts/admin.vue | 관리자 전체, 320px 밝은 Ghost형 사이드바, 우측 전체 높이 캔버스, 멤버 수 표시, 하단 사용자 드롭다운·설정, `내 프로필` 멤버 편집 이동, 게시글 `+` 새 글 진입, 글 작성/수정 화면의 전체 화면 편집 모드와 문서 스크롤 잠금 | | layouts/page.vue | 고정 페이지 전체 화면 | | app.vue | 공개 사이트 설정 기반 파비콘 head 링크와 기본 title template | ## Composables | 파일 | 용도 | |------|------| | composables/formatPostDate.js | 공개 화면 게시일 `YYYY.MM.DD` 포맷 | | composables/useAdminToast.js | 관리자 우측 상단 토스트(성공·오류·안내; 모달보다 위 z-index) | ## 공유 라이브러리(서버·클라이언트 공통) | 파일 | 용도 | |------|------| | lib/navigation-editor-tree.js | 관리자 메뉴 UI·서버 `renumberSortOrderByTree`가 쓰는 `buildNavigationEditorTree` | | lib/markdown-content-normalizer.js | 관리자 Markdown-first 전환 후 레거시 블록 배열·객체 본문 값을 저장용 마크다운 문자열로 변환 | ## 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`) 재확인 | ## 사이트 컴포넌트 | 파일 | 화면 위치 | |------|-----------| | components/auth/AuthPasswordVisibilityToggle.vue | 로그인·회원가입 비밀번호 표시/숨김 토글(SVG, scoped 스타일·`field-name`으로 접근성 레이블 구분) | | components/site/SiteHeader.vue | 모든 공개 페이지 상단, 이미지 로고 fallback, `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`), 푸터 `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 | 오른쪽 사이드바, 공개 사이트 이미지 로고 fallback, `lg+`는 고정 열 높이·스티키, 모바일은 본문 아래 전체 너비, 하단 푸터 `pr-3` | | components/site/MainColumn.vue | 메인 화면 중앙, `lg:max-w-[720px]`로 본문 상한 | | components/site/PostCard.vue | 목록의 게시물 카드, 대표 이미지 썸네일, 카드 hover 인터랙션, 태그는 있을 때만 메타에 표시 | | components/site/TagHeader.vue | 태그 페이지 헤더 | | components/comments/PostComments.vue | 게시물 상세 `#comments` 영역, 회원 댓글/답글(1단) 작성 및 목록 표시, 작성자 썸네일/좋아요/상대시간 표시 | ## 관리자 컴포넌트 | 파일 | 화면 위치 | |------|-----------| | components/admin/AdminPostForm.vue | 관리자 글 작성/수정 폼, 제목 입력 text-3xl, Ghost 스타일 전체 화면 에디터, 변경사항 기반 저장 버튼 활성화, 저장 클릭 시 전체 화면 발행 모달(행 접기/펼침, Ghost 동일 SVG 아이콘, 상태 요약 후 발행/초안/비공개 선택, 발행 시에만 시점 행·즉시/예약·datetime-local), 좌우 분할 설정 패널, 설정 패널 전환 애니메이션, Post URL 보기 액션, 중립 톤 삭제 액션, 대표 이미지 hover 액션과 업로드/미디어 선택 확정, 제목 IME Enter 가드, SVG 닫기 아이콘 배지형 태그 입력(한글 유지), 로컬 자동 저장(툴바 상태 옆 복원·무시), 미저장 변경사항 이탈 확인, 검색 노출 제외(noindex), 저장 시 제목·요약을 SEO 메타로 반영, 미리보기 요청 | | components/admin/AdminPageForm.vue | 관리자 페이지 작성/수정 폼, 대표 이미지 선택 | | components/admin/AdminMarkdownEditor.vue | 관리자 글 Markdown-first 에디터, textarea 기반 범위 선택·복사/붙여넣기, HTML 클립보드 마크다운 변환, Enter 새 문단·Shift+Enter 백슬래시 hard break 줄바꿈 입력, 작성 모드 왼쪽 바깥 absolute 논리 줄 번호 거터·거터 스크롤 동기화·스크롤바 숨김, 작성/미리보기 전환(`Cmd/Ctrl+E`)과 커서 복원, 작성 모드 툴바 마크다운 삽입, 미리보기 모드 툴바 숨김, 이미지·갤러리 업로드 및 미디어 라이브러리 삽입, 현재 이미지·갤러리 편집 패널 | | components/admin/AdminBlockEditor.vue | 관리자 글 블록형 에디터, 이미지/갤러리/콜아웃/토글/임베드 블록, 콜아웃 Emoji on/off·이모지 프리셋·배경 프리셋 선택(우측 고정 설정 패널), 갤러리 복수 미디어 선택·이미지 수별 열 배치·삽입 위치 표시 드래그 순서 변경, 한글 조합 입력 처리, Shift+Enter 줄바꿈, 코드 블록 단축 변환, AFFiNE 참고 세로 막대형 블록 핸들 선택/삭제/드래그 이동과 삽입선 표시, 하단 빈 입력 블록 유지, 본문 placeholder 표시 | | components/admin/AdminNavPrimaryBranch.vue | 관리자 상단 네비 트리(테이블·태그와 동일한 행 드래그 하이라이트, 하위·삭제) | | 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 `
` 처리, 확장 블록 파싱 | | components/content/ProseHeading.vue | h1~h6 제목, 기본 mt-12 제거 | | components/content/ProseImage.vue | 본문 내 이미지 | | components/content/ProseList.vue | 목록 | | components/content/ProseBlockquote.vue | 인용구 | | components/content/ProseButton.vue | 버튼 | | components/content/ProseCallout.vue | Callout 카드(Emoji 표시/숨김, 배경 프리셋, 상단 여백 중심) | | components/content/ProseToggle.vue | Toggle 카드 | | components/content/ProseVideo.vue | 비디오 | | components/content/ProseAudio.vue | 오디오 | | components/content/ProseFile.vue | 파일 | | components/content/ProseProduct.vue | 상품 카드 | | components/content/ProseBookmark.vue | 본문 북마크 카드(썸네일·도메인·`http(s)` 외부 링크) | | components/content/ProseSignup.vue | 본문 회원가입·뉴스레터 CTA 카드 | | components/content/ProseHeaderCard.vue | 헤더 카드 | | components/content/ProseEmbed.vue | YouTube·Twitter/X iframe 임베드, 기타 `http(s)` 외부 링크 | ## 관리자 페이지 | 파일 | 화면 | |------|------| | pages/admin/index.vue | 대시보드 | | pages/admin/login.vue | 관리자 로그인(이메일·비밀번호 모두 입력 시에만 제출 버튼 활성) | | pages/admin/posts/index.vue | 글 목록, 예약 발행 상태 표시, 읽기 전용 태그 배지, 삭제는 휴지통 아이콘·기본 낮은 강조 | | pages/admin/posts/new.vue | 글 작성, Ghost 스타일 작성 폼, 저장 토스트 | | pages/admin/posts/[id].vue | 글 수정, Ghost 스타일 작성 폼, 저장/삭제 토스트 | | pages/admin/posts/preview.vue | 글 미리보기(공개 상세와 동일한 중앙 컬럼·수평 패딩) | | pages/admin/pages/index.vue | 페이지 목록 | | pages/admin/pages/new.vue | 페이지 작성, 저장 토스트 | | pages/admin/pages/[id].vue | 페이지 수정, 저장/삭제 토스트 | | pages/admin/media/index.vue | 미디어 관리, **미디어 라이브러리/썸네일** 탭, 검색은 파일명·게시물 사용처 제목만, 라이브러리: 폴더 트리·드래그 이동 등, 썸네일: 미참조 파일 삭제·이름 변경 가능, 상세 모달(연결 회원·폴더 편집·**다운로드**) | | pages/admin/navigation/index.vue | 메뉴 관리: 상단/하단 탭, 테이블+행 드래그(태그 메인과 동일 톤), `useAdminToast` | | pages/admin/tags/index.vue | 태그 관리(메인 태그 드래그 정렬·일반 강등, 일반 태그 검색/메인 전환/삭제), 액션 피드백 토스트, 순서 변경 시에만 정렬 저장 활성 | | pages/admin/tags/new.vue | 태그 생성 | | pages/admin/tags/[id].vue | 태그 수정 | | pages/admin/settings/index.vue | 사이트 설정(이름, 설명, URL, 1:1 로고 업로드·파비콘 생성, 저작권 문구) | | pages/admin/members/index.vue | 관리자 멤버 목록(Ghost형 테이블, 검색, 조건 필터, 멤버 추가 버튼, 닉네임+이메일, 가입일+최근 활동, IP, 댓글 수, 활동 상태 텍스트) | | pages/admin/members/new.vue | 관리자 멤버 추가(썸네일 URL, 이름, 이메일, 레이블, 관리자 노트) | | pages/admin/members/[id].vue | 관리자 멤버 상세/수정(회원 요약, 가입 정보, 활동 요약, 기본 정보 저장, 삭제 후 목록 이동) | ## 공개 페이지 | 파일 | 화면 | |------|------| | pages/index.vue | 홈, 중앙 Hero/Featured/Latest 섹션의 내부 컨테이너 보더 정렬과 리스트형 latest 카드, Latest 메타는 태그가 있을 때만 태그 배지 표시, Featured는 모바일 터치 가로 스크롤·스냅과 끝에서 화살표 비활성 | | pages/posts/index.vue | 게시물 전체 목록, 태그는 있을 때만 카드 메타에 표시 | | pages/posts/[slug].vue | `/post/:slug` 리다이렉트 | | pages/post/[slug].vue | 블로그 글 상세, 첫 태그가 있을 때만 메타 행에 태그 링크, 게시물 SEO/OG 메타 출력, 공유 모달(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 | | 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/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 | 댓글 조회/생성 저장소 | ## 데이터베이스 | 파일 | 기능 | |------|------| | 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/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`) 컬럼 추가 | ## 설정/배포 | 파일 | 기능 | |------|------| | package.json | Nuxt 실행 스크립트와 의존성 | | nuxt.config.js | Nuxt 앱 설정, `tailwindcss.cssPath`로 `main.css` 단일 엔트리, Tailwind 모듈, 관리자 QA를 위한 개발 도구 비활성화, 회원 썸네일 최소/최대 해상도·품질 런타임 설정 | | tailwind.config.js | Tailwind 테마 설정 | | assets/css/main.css | 전역 스타일, `#fcfcfc` 단일 배경 기준, 좌측 사이드바/그리드 전환 애니메이션, 네비게이션 세로 바 hover 효과 | | composables/useMenuState.js | 좌측 메뉴 열림 상태·`closeMenu`(모바일 백드롭 등) | | composables/useThemeMode.js | 사용자 화면 라이트/다크 테마 상태 관리 | | middleware/admin-auth.global.js | 관리자 페이지 접근 인증 | | scripts/dev-server.js | 로컬 개발 서버 링크 요약 출력 | | scripts/migrate-development-db.js | 로컬 개발 DB 마이그레이션 실행 | | .env.example | 환경 변수 예시 | | Dockerfile | NAS 운영 이미지 빌드 | | docker-compose.yml | NAS 컨테이너 실행 초안 |