v1.10.88 품질·보안 개선과 미디어 카탈로그 database 전환을 반영한다.
세션·로그인 제한, ZIP/업로드 스트리밍, CSP 최소 강제와 Report-Only, Playwright 격리 검증을 추가하고 미디어 목록을 reconcile 후 database 모드로 고정한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
106
docs/map.md
106
docs/map.md
@@ -35,7 +35,7 @@
|
||||
| lib/markdown-content-normalizer.js | 관리자 Markdown-first 전환 후 레거시 블록 배열·객체 본문 값을 저장용 마크다운 문자열로 변환 |
|
||||
| lib/markdown-block-context.js | 관리자 Markdown textarea·라이브 편집 포커스 위치 기준 이미지·갤러리·링크·iframe·HTML·인용·콜아웃·코드·토글 블록 설정 패널 대상 판별, 코드 fenced 블록 여닫는 펜스 쌍 판별 |
|
||||
| lib/markdown-iframe-embed.js | 게시물 본문 iframe 블록의 코드 판별과 안전 속성 추출 |
|
||||
| lib/markdown-html-block.js | 게시물 본문 HTML 블록의 실행성 태그·속성 제거 |
|
||||
| lib/markdown-html-block.js | 게시물 본문 HTML 블록의 parser 기반 허용 태그·속성 sanitizer, 실행 URL·인라인 style 제거와 새 창 링크 rel 보정 |
|
||||
| lib/markdown-callout.js | 인용 막대 색상·콜아웃 배경색 옵션, 선언 줄 파싱·직렬화 |
|
||||
| lib/brand-color.js | 사이트 브랜드 컬러 기본값·hex 검증·정규화 |
|
||||
| lib/markdown-image.js | 이미지 마크다운 직렬화·파싱, 단독 이미지 URL 판별 |
|
||||
@@ -46,6 +46,8 @@
|
||||
| lib/analytics-shared.js | 통계 추적 경로 필터·체류/스크롤 상수(클라이언트·서버 공용) |
|
||||
| lib/analytics.js | 서버 전용 visitor/session hash(`node:crypto`) |
|
||||
| lib/analytics-traffic.js | referrer·User-Agent 기반 유입원·디바이스·검색 키워드 축약 분류 |
|
||||
| lib/csp-report.js | CSP 보고 Content-Type·32KB/20건 제한 상수, payload 검증, 문서 경로·차단 origin·브라우저 계열 최소화 |
|
||||
| lib/media-catalog.js | 업로드 URL·저장 키 정규화, 미디어 종류·원본/파생 역할 판별, 콘텐츠 미디어 참조 추출, PostgreSQL LIKE 리터럴 이스케이프 |
|
||||
| lib/social-links.js | 사이트 설정 SNS 링크 아이콘 프리셋·사용자 SVG 정리·URL 자동 보정·레거시 JSON 문자열 복구·공개 노출 목록 생성 |
|
||||
| server/utils/backup-storage-summary.js | 관리자 사이트 설정 백업 현황용 업로드 파일 스캔·원본/자동 생성 이미지/프로필/내보내기 파일 용량 집계 |
|
||||
|
||||
@@ -55,6 +57,11 @@
|
||||
|------|------|
|
||||
| docs/shortcuts.md | 사이트 단축키, 작성 약어, 슬래시 명령, Markdown 약식 문법 정리 |
|
||||
| docs/update-log/v1.0.md | 블로그 업데이트 공지 초안(v0.0~v1.0 회고 기록) |
|
||||
| docs/update-log/v1.1.md | 블로그 업데이트 공지 초안(v1.0 개발 구간 기록) |
|
||||
| docs/update-log/v1.2.md | 블로그 업데이트 공지 초안(v1.1 개발 구간 기록) |
|
||||
| docs/update-log/v1.5.md | 블로그 업데이트 공지 초안(v1.2~v1.4 개발 구간 기록) |
|
||||
| docs/update-log/v1.6.md | 블로그 업데이트 공지 초안(v1.5 개발 구간 기록) |
|
||||
| docs/update-log/v1.10.md | 블로그 업데이트 공지 초안(v1.6~v1.9 개발 구간 기록) |
|
||||
|
||||
## Nuxt 모듈
|
||||
|
||||
@@ -74,6 +81,23 @@
|
||||
| scripts/backfill-post-body-thumbnails-production.sh | npm 없는 NAS 호스트에서 앱 컨테이너 내부 Node로 본문 표시용 WebP 백필 실행 |
|
||||
| scripts/backfill-page-cover-thumbnails-production.sh | npm 없는 NAS 호스트에서 앱 컨테이너 내부 Node로 Pages 커버 썸네일 백필 실행 |
|
||||
| scripts/generate-adsense-token.js | AdSense Management API refresh token 발급과 접근 가능한 계정 이름 확인 |
|
||||
| scripts/run-playwright-tests.js | API/E2E 프로젝트별 격리 환경 준비·Playwright 실행·정리 |
|
||||
| scripts/playwright-test-environment.js | `_test` PostgreSQL 컨테이너·임시 업로드 루트·worker 비활성화 환경 구성 |
|
||||
| scripts/reconcile-media-catalog.js | loopback 비운영 DB만 허용하는 파일 비파괴 미디어 카탈로그 수동 reconcile |
|
||||
|
||||
## 테스트
|
||||
|
||||
| 파일 | 용도 |
|
||||
|------|------|
|
||||
| playwright.config.js | Playwright API/E2E 프로젝트, 단일 worker, 전용 Nuxt 서버·trace 설정 |
|
||||
| docker-compose.test.yml | 실행마다 생성·폐기하는 PostgreSQL 16 테스트 DB·볼륨·네트워크 |
|
||||
| tests/markdown-html-block.test.js | HTML sanitizer 단위 회귀 테스트 |
|
||||
| tests/multipart-file-upload.test.js | multipart 스트리밍·제한 단위 회귀 테스트 |
|
||||
| tests/csp-report.test.js | CSP URL 최소화·payload 형식 단위 회귀 테스트 |
|
||||
| tests/media-catalog.test.js | 미디어 URL·역할·참조·LIKE 이스케이프 단위 회귀 테스트 |
|
||||
| tests/playwright/api/core-api.spec.js | 인증·부분 설정 저장·공개 목록·CSP·미디어 reconcile/fallback·세션 무효화 API 통합 10건 |
|
||||
| tests/playwright/e2e/admin-guard-and-settings.spec.js | 설정 카드 독립 저장과 미저장 이탈 취소 브라우저 E2E 2건 |
|
||||
| tests/playwright/e2e/admin-publish.spec.js | 관리자 로그인·게시물 발행·공개 화면 확인 브라우저 E2E 1건 |
|
||||
|
||||
## DB 마이그레이션
|
||||
|
||||
@@ -90,6 +114,9 @@
|
||||
| db/migrations/064_posts_admin_pinned.sql | 관리자 글 목록 전용 상단 고정 컬럼·정렬 인덱스 추가 |
|
||||
| db/migrations/065_public_search_index.sql | 공개 통합 검색용 `search_text` 컬럼·자동 갱신 트리거·`pg_trgm` GIN 인덱스 추가 |
|
||||
| db/migrations/066_analytics_active_session_ip.sql | 실시간 접속 세션 IP 표시용 `analytics_active_sessions.ip_address` 컬럼 추가 |
|
||||
| db/migrations/067_users_session_version.sql | 비밀번호 변경 후 기존 로그인 세션 무효화용 `users.session_version` 컬럼 추가 |
|
||||
| db/migrations/068_csp_violation_aggregates.sql | CSP 정책 버전·문서 경로·지시어·차단 origin·브라우저 계열 위반 집계 테이블 추가 |
|
||||
| db/migrations/069_media_catalog.sql | `media_metadata` 파일 카탈로그 필드·상태·관계, `media_references`, `media_catalog_state` 추가 |
|
||||
|
||||
## 서버 미들웨어
|
||||
|
||||
@@ -97,6 +124,10 @@
|
||||
|------|------|
|
||||
| server/middleware/admin-api-session.js | `/admin/api/*` 요청마다 관리자 세션과 현재 DB 권한(`owner`/`admin`) 재확인 |
|
||||
| server/middleware/html-page-renderer.js | HTML 문서 모드 고정 페이지(`/pages/:slug`)를 Nuxt 렌더링 대신 `text/html` 원문으로 응답 |
|
||||
| server/middleware/security-headers.js | 전역 보안 헤더 적용, `/pages/**` 강제 CSP 제외 결정 |
|
||||
| server/utils/security-headers.js | 최소 강제 CSP와 사용자 코드·광고 호환 Report-Only·Reporting API 헤더 구성 |
|
||||
| server/utils/csp-report-request-limit.js | CSP 보고 IP 해시 기준 분당 60회·버킷 상한 제한 |
|
||||
| server/utils/upload-root.js | 일반 `public/uploads`와 Playwright 전용 임시 업로드 루트 분리 |
|
||||
| server/routes/uploads/[...path].get.js | 런타임 업로드 파일 제공 API(`/app/public/uploads` 볼륨 파일을 `/uploads/**`로 스트리밍, 원본 장기 캐시·파생 이미지 재검증 캐시·조건부 요청 304 지원) |
|
||||
| server/routes/sitemap.xml.get.js | 공개 sitemap XML(`/sitemap.xml`) |
|
||||
| server/routes/robots.txt.get.js | 공개 robots.txt(`/robots.txt`, sitemap 위치 안내) |
|
||||
@@ -105,10 +136,18 @@
|
||||
| server/routes/rss.get.js | 공개 RSS 2.0 피드 별칭(`/rss`) |
|
||||
| server/plugins/site-custom-code.js | 공개 Nuxt HTML 응답에 사이트 설정 헤더·푸터 코드 삽입(`/admin`, `/api`, `/uploads`, `/_nuxt`, `/ads.txt` 제외) |
|
||||
| server/utils/post-thumbnail-image.js | 게시물 업로드 이미지의 카드 썸네일·Pages 3:4 커버 썸네일·본문 표시용 1600px/720px WebP·라이트박스용 2560px WebP 이미지 URL·디스크 경로·생성 가능 여부·본문 이미지 추출 규칙 |
|
||||
| server/utils/media-library.js | 관리자 미디어 파일 스캔·폴더 메타·사용처 계산·삭제/이름 변경, 미디어 참조 전용 게시물·페이지 조회 기반 원본/파생 이미지 사용처 연결 |
|
||||
| server/utils/media-library.js | 관리자 미디어 파일 스캔·폴더 메타·사용처 계산·삭제/이름 변경, 30초 전체 목록 공유 캐시·동시 요청 단일 실행·파일 변경 시 무효화, 미디어 참조 전용 게시물·페이지 조회 기반 원본/파생 이미지 사용처 연결 |
|
||||
| server/utils/sitemap.js | 공개 sitemap XML·robots.txt 생성 |
|
||||
| server/utils/rss-feed.js | 공개 발행글 기반 RSS 2.0 XML 생성, 게시물 이미지 Media RSS 썸네일 출력 |
|
||||
|
||||
## 서버 저장소
|
||||
|
||||
| 파일 | 용도 |
|
||||
|------|------|
|
||||
| server/repositories/csp-report-repository.js | 민감 원문 없이 정규화된 CSP 위반 차원을 PostgreSQL에 누적 집계 |
|
||||
| server/repositories/media-catalog-repository.js | 미디어 파일·참조 dual-write, DB SQL 목록, 준비 상태 검사, 파일 비파괴 reconcile·missing 표시 |
|
||||
| server/repositories/content-repository.js | 게시물·페이지·태그·사이트 설정 저장 후 미디어 참조 최선 노력 동기화 |
|
||||
|
||||
## 사이트 컴포넌트
|
||||
|
||||
| 파일 | 화면 위치 |
|
||||
@@ -118,9 +157,9 @@
|
||||
| components/site/SiteAnnouncementBar.vue | 공개 사이트 상단 어나운스 배너(문구·선택 링크·hex 배경색·텍스트 정렬·닫기) |
|
||||
| components/site/SiteHeader.vue | 모든 공개 페이지 상단, 사이트 이름 텍스트 브랜드, `grid-cols-3`로 검색 패널 중앙 정렬(`md+`), 우측 사용자 아바타 드롭다운(아바타 없거나 비로그인 시 사람 아이콘), `/`·`SiteSearchModal` |
|
||||
| components/site/SiteSearchModal.vue | `Teleport`·전체 화면 딤·Tags/Posts 결과·일치 구간 강조, 열림 시 `html.site-search-open` 스크롤 잠금, IME 조합 중 표시값 디바운스 반영·조합 종료 후 최종 검색어 즉시 반영과 공백·Unicode 정규화 |
|
||||
| components/site/LeftSidebar.vue | 왼쪽 사이드바, `lg+`는 `sticky`+고정 높이+내부 무스크롤바 스크롤, `lg` 미만은 고정 슬라이드 패널, 상단 메뉴는 `SidebarPrimaryNavList`+`provide`로 트리·펼침 상태(`sori-primary-nav-expanded`), 태그 Categories 아래 공개 `GET /api/navigation`의 `recommended` 카드 목록(수동 썸네일 > 서버 캐시 파비콘 > 외부 프록시 fallback), Authors 영역은 비공개, 푸터 `footer` 링크는 `flex-wrap`·테마 버튼 `shrink-0`, 태그 카테고리·테마 점은 `site-sidebar-nav-row` 호버 |
|
||||
| components/site/LeftSidebar.vue | 왼쪽 사이드바, `lg+`는 `sticky`+상단 크롬 CSS 변수 기준 높이+내부 무스크롤바 스크롤, `lg` 미만은 같은 CSS 변수 아래의 고정 슬라이드 패널, 상단 메뉴는 `SidebarPrimaryNavList`+`provide`로 트리·펼침 상태(`sori-primary-nav-expanded`), 태그 Categories 아래 공개 `GET /api/navigation`의 `recommended` 카드 목록(수동 썸네일 > 서버 캐시 파비콘 > 외부 프록시 fallback), 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 | 오른쪽 사이드바, 일반 화면은 설정 기반 사이트 로고 48px 정사각형 고정·SNS Follow(프리셋·사용자 SVG, 16px 아이콘 중앙 정렬)·오른쪽 사이드 광고를 표시, 게시글 상세 데스크톱은 블로그 소개·Follow 대신 최상단 H1~H3 TOC와 TOC 아래 게시물 사이드 광고(모바일 숨김, 스크롤 위치 기반 활성 표시·내부 자동 스크롤, 세로 기준선), About 영역은 비공개, `lg+` 스티키이며 데스크톱 외곽 구분선은 레이아웃 오른쪽 컬럼이 담당 |
|
||||
| components/site/RightSidebar.vue | 오른쪽 사이드바, 일반 화면은 설정 기반 사이트 로고 48px 정사각형 고정·SNS Follow(프리셋·사용자 SVG, 16px 아이콘 중앙 정렬)·오른쪽 사이드 광고를 표시, 게시글 상세 데스크톱은 블로그 소개·Follow 대신 최상단 H1~H3 TOC와 TOC 아래 게시물 사이드 광고(모바일 숨김, 스크롤 위치 기반 활성 표시·내부 자동 스크롤, 세로 기준선), About 영역은 비공개, `lg+` 스티키 top·높이는 상단 크롬 CSS 변수를 사용하며 데스크톱 외곽 구분선은 레이아웃 오른쪽 컬럼이 담당 |
|
||||
| components/site/SiteAdSlot.vue | 사이트 설정 Ads HTML 코드 렌더링, 메인 피드·메인 인피드·오른쪽 사이드·게시물 오른쪽 사이드·게시물 본문 상단·인아티클·하단 광고 슬롯 |
|
||||
| components/site/MainColumn.vue | 메인 화면 중앙, `lg:max-w-[720px]`로 본문 상한 |
|
||||
| components/site/HomeHero.vue | 홈 상단 720px 커버 배너, 라이트·다크 테마별 이미지 교체, 왼쪽 하단 오버레이 제목·본문 |
|
||||
@@ -128,7 +167,7 @@
|
||||
| components/site/PostCardMedia.vue | 게시물 카드 썸네일(`featuredImageThumbnail` 우선, 없으면 대표 이미지 원본 사용. 대표 이미지 없으면 모바일 3줄·`sm` 이상 4줄 제목 placeholder 표시, 이미지 유무와 관계없이 썸네일 영역 크기 고정) |
|
||||
| components/site/SitePagination.vue | 공개 목록 공용 번호형 페이지네이션, 이전·다음 화살표와 첫/끝/현재 주변 페이지 직접 이동, 많은 페이지의 `...` 접기, 모바일 가로 스크롤 |
|
||||
| components/site/TagHeader.vue | 태그 페이지 헤더 |
|
||||
| components/comments/PostComments.vue | 게시물 상세 `#comments` 영역, 회원 댓글/답글(1단) 작성 및 목록 표시, 기본 정렬 최신순(최신순·인기순·오래된순 선택), 입력값 기반 등록 버튼 활성화, 작성자 썸네일/좋아요/상대시간 표시 |
|
||||
| components/comments/PostComments.vue | 게시물 상세 `#comments` 영역, 회원 댓글/답글(1단) 작성 및 목록 표시, slug 변경 시 입력·답글·오류·좋아요 상태 초기화와 지연 응답 폐기, 기본 정렬 최신순(최신순·인기순·오래된순 선택), 입력값 기반 등록 버튼 활성화, 작성자 썸네일/좋아요/상대시간 표시 |
|
||||
|
||||
## 관리자 컴포넌트
|
||||
|
||||
@@ -139,8 +178,8 @@
|
||||
| components/admin/AdminAdsSettingsCard.vue | 관리자 사이트 설정의 위치별 Ads 코드 카드(메인 피드·메인 인피드·오른쪽 사이드·게시물 오른쪽 사이드·게시물 본문 상단·인아티클·하단) |
|
||||
| components/admin/AdminPostExportFileRow.vue | 관리자 사이트 설정 내보내기 작업의 분할 파일 선택 행 |
|
||||
| components/admin/AdminMediaVideoThumbnail.vue | 관리자 미디어 목록 비디오 항목의 초반 프레임 캔버스 썸네일 |
|
||||
| components/admin/AdminPostForm.vue | 관리자 글 작성/수정 폼, Ghost형 툴바(왼쪽 상태 텍스트·Publish/Update/Unpublish/Unschedule, 서버 반영 상태 기준 분기), 초안만 서버 디바운스 자동 저장·자동 저장 실패 payload 반복 재시도 차단·신규 임시 슬러그·중복 슬러그 필드 하단 오류 표시·중복 슬러그 중 Publish/Update/최종 저장 비활성화·저장 중 추가 변경 재자동저장·발행 저장 중 이탈 확인·발행·예약·멤버십·비공개 상태 저장, 미저장 비교에서 태그 표시명 보조값 제외, 공개 상태 전환 시 빈 발행 시각 현재 시각 보정, 발행 모달(중앙 배치), 좌우 설정 패널(작은 화면은 오른쪽 고정 오버레이), 오른쪽 `View Post` 링크, 오른쪽 하단 본문 통계(단어·문자·공백·읽기 시간·블록·이미지), 미리보기 emit·미저장 이탈 가드, 자동 생성 썸네일을 숨기는 원본 전용 대표 이미지 선택(서버 페이지네이션·파일명/사용처 검색·번호형 페이지 이동·작은 파생 이미지 우선 미리보기·고정 높이 모달), 대표 이미지 본문 상단 표시 토글, 추천 글 토글, 사이트 설정 기준 태그 최대 개수 제한, 태그 색상 배지 다중 입력·최근 사용 태그 5개 우선 추천·메인 태그 드롭다운·부분 검색 추천, 새 태그 입력명 유지와 `/`→`-` 슬러그 변환 |
|
||||
| components/admin/AdminPageForm.vue | 관리자 페이지 작성/수정 폼, 게시글 작성과 같은 전체 화면 에디터·상단 저장 툴바·접이식 오른쪽 설정 패널, 페이지 공개 상태 선택, HTML 문서 기본 모드, 홈 Pages 진열장 노출 메타와 등록된 페이지 섹션 검색형 선택, 빈 본문/`!`+Tab HTML 골격 자동 완성, 항상 보이는 일반 텍스트/HTML 모드 선택, 한글 제목 영문 슬러그 자동 변환, HTML textarea 커서 위치 파일 URL 삽입, HTML 태그 내부 스마트 따옴표 정규화 |
|
||||
| components/admin/AdminPostForm.vue | 관리자 글 작성/수정 폼, Ghost형 툴바(왼쪽 상태 텍스트·Publish/Update/Unpublish/Unschedule, 서버 반영 상태 기준 분기), 초안만 서버 디바운스 자동 저장·자동 저장 실패 payload 반복 재시도 차단·자동 저장 실패/진행 중 이탈 차단·신규 임시 슬러그·중복 슬러그 필드 하단 오류 표시·중복 슬러그 중 Publish/Update/최종 저장 비활성화·저장 중 추가 변경 재자동저장·발행 저장 중 이탈 확인·발행·예약·멤버십·비공개 상태 저장, 미저장 비교에서 태그 표시명 보조값 제외, 공개 상태 전환 시 빈 발행 시각 현재 시각 보정, 발행 모달(중앙 배치), 좌우 설정 패널(작은 화면은 오른쪽 고정 오버레이), 오른쪽 `View Post` 링크, 오른쪽 하단 본문 통계(단어·문자·공백·읽기 시간·블록·이미지), 미리보기 emit·미저장 이탈 가드, 자동 생성 썸네일을 숨기는 원본 전용 대표 이미지 선택(서버 페이지네이션·파일명/사용처 검색·번호형 페이지 이동·작은 파생 이미지 우선 미리보기·고정 높이 모달), 대표 이미지 본문 상단 표시 토글, 추천 글 토글, 사이트 설정 기준 태그 최대 개수 제한, 태그 색상 배지 다중 입력·최근 사용 태그 5개 우선 추천·메인 태그 드롭다운·부분 검색 추천, 새 태그 입력명 유지와 `/`→`-` 슬러그 변환 |
|
||||
| components/admin/AdminPageForm.vue | 관리자 페이지 작성/수정 폼, 게시글 작성과 같은 전체 화면 에디터·상단 저장 툴바·접이식 오른쪽 설정 패널, 저장 payload 기준 미저장 비교·라우트/브라우저 이탈 확인, 페이지 공개 상태 선택, HTML 문서 기본 모드, 홈 Pages 진열장 노출 메타와 등록된 페이지 섹션 검색형 선택, 빈 본문/`!`+Tab HTML 골격 자동 완성, 항상 보이는 일반 텍스트/HTML 모드 선택, 한글 제목 영문 슬러그 자동 변환, HTML textarea 커서 위치 파일 URL 삽입, HTML 태그 내부 스마트 따옴표 정규화 |
|
||||
| components/admin/AdminMarkdownEditor.vue | 관리자 글 Markdown-first 에디터, 라이브·소스 모드 `/` 슬래시 명령(`/표` 기본 표 템플릿 포함)·미디어 모달(이미지·갤러리·비디오·오디오·파일, 업로드 탭 기본·첫 순서, 업로드 완료 파일 자동 선택, 라이브러리 탭은 `/admin/api/media?paged=1` 서버 페이지 응답·파일명/사용처 제목 검색·번호형 페이지 이동, 카드·본문·라이트박스·Pages 커버 자동 생성 이미지 숨김, 원본 URL 선택 유지·갤러리 선택 순서 배지·목록 미리보기는 720px 본문 파생 이미지 또는 카드 썸네일 우선, 검색 결과 수와 무관한 고정 높이 패널, 업로드 중 중복 업로드·닫기 차단·로딩 표시), 코드 블록 본문 슬래시 명령 비활성화, 커서 블록 컨텍스트·선택 텍스트 색상 컨텍스트 `block-panel` emit, 에디터 본문 `Cmd/Ctrl+Z` 히스토리와 선택 위치 복원, 라이브 이미지 설정 패널·이미지↔갤러리 드래그 변환(`merge-images-to-gallery`·`insert-image-to-gallery`·`extract-gallery-image`), 소스·라이브 `Cmd+Shift+K` 줄 삭제, 소스·라이브 `Cmd/Ctrl+K` 링크 삽입, 코드·콜아웃·토글 내부 줄 삭제, 라이브 fenced 블록 현재 닫는 줄 기준 교체, 블록 패널 바깥 클릭·지원 블록 밖 커서 이동 시 닫기·미디어 모달 중 유지, 인용 마지막 줄 아래 방향키 외부 문단 포커스 이동, 인용·콜아웃·코드·토글 선언 줄 옵션 수정, IME 조합 중 블록 패널 유지, 소스 모드 wrap 라인 번호 보정·라이브↔소스 위치 복원(코드·콜아웃·토글 선언 줄은 본문 줄로 보정), 라이브 슬래시 명령 후 포커스 복원 지연 |
|
||||
| components/admin/AdminEditorBlockPanel.vue | 게시물 설정 사이드바 오버레이 블록 설정(선택 텍스트 색상, 단일 이미지 대표 너비 셀렉트(전체·갤러리 2장 1칸·갤러리 3장 1칸·갤러리 3장 2칸·직접 입력)·직접 너비·이미지·갤러리·링크·iframe·HTML·인용 배경색·콜아웃 제목·아이콘·배경색·코드·토글), 갤러리 선택 이미지 강조 |
|
||||
| components/admin/AdminBlockEditor.vue | 관리자 글 블록형 에디터, 이미지/갤러리/콜아웃/토글/HTML 블록, 콜아웃 Emoji on/off·이모지 프리셋·인용과 같은 배경 프리셋 선택(우측 고정 설정 패널), 갤러리 복수 미디어 선택·이미지 수별 열 배치·삽입 위치 표시 드래그 순서 변경, 한글 조합 입력 처리, Shift+Enter 줄바꿈, 코드 블록 단축 변환, AFFiNE 참고 세로 막대형 블록 핸들 선택/삭제/드래그 이동과 삽입선 표시, 하단 빈 입력 블록 유지, 본문 placeholder 표시 |
|
||||
@@ -186,7 +225,7 @@
|
||||
| components/content/ProseSignup.vue | 본문 회원가입·뉴스레터 CTA 카드 |
|
||||
| components/content/ProseHeaderCard.vue | 헤더 카드 |
|
||||
| components/content/ProseEmbed.vue | 상단 외부 여백 없이 하단 여백만 두는 YouTube 영상 iframe, X/Twitter 소셜 iframe, Mastodon `/embed` iframe, 제한된 사용자 iframe HTML, 기타 `http(s)` 외부 링크 |
|
||||
| components/content/ProseHtml.vue | `:::html` 본문 HTML 렌더링, 표 기본 스타일과 실행성 HTML 제거 |
|
||||
| components/content/ProseHtml.vue | `:::html` 본문 HTML 렌더링, 표 기본 스타일과 허용 목록 sanitizer 적용 |
|
||||
|
||||
## 관리자 페이지
|
||||
|
||||
@@ -209,7 +248,7 @@
|
||||
| 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·저작권 읽기 행), **SNS 정보**(아이콘 프리셋+주소 목록형 관리), **메인 화면**(라이트·다크 커버 상하 개별 프리뷰·드롭존 업로드·오버레이 텍스트), **어나운스 바**(사용 토글·맞춤 설정·hex 배경색·텍스트 정렬·읽기 모드 비활성 톤), **스팸 필터**(가입 금지 닉네임), **백업 현황** 텍스트 카드(콘텐츠 수량·미디어 용량·자동 생성 이미지·내보내기 파일·큰 파일), **게시물 내보내기** 독립 카드와 펼침형 전체·연도·월·직접 날짜 범위 작업 요청·목표 ZIP 용량·ZIP당 최대 게시물 수, 작업이 있을 때만 표시되는 **최근 내보내기 작업** 별도 카드(준비 완료 배지 숨김·진행 중 진행도·만료일·파일 체크 선택·전체 선택·선택 파일 다운로드·실패 작업 재시도·실패 상세 오류·작업 삭제), **게시물 가져오기** 독립 카드와 펼침형 ZIP 드롭존·적용 버튼·완료 요약·누락 자산 경고 표시, 진행 중 요청 버튼 잠금 |
|
||||
| pages/admin/settings/index.vue | 사이트 설정 Ghost형 전체 화면, 카드별 필드만 PATCH하고 성공 필드만 폼에 반영하는 독립 저장, **POST 설정**(`showPostUpdatedAt` 토글·읽기 모드 비활성 톤), 블로그 제목·설명 읽기 행, **사이트 정보**(로고 미등록 점선 박스·URL·저작권 읽기 행), **SNS 정보**(아이콘 프리셋+주소 목록형 관리), **메인 화면**(라이트·다크 커버 상하 개별 프리뷰·드롭존 업로드·오버레이 텍스트), **어나운스 바**(사용 토글·맞춤 설정·hex 배경색·텍스트 정렬·읽기 모드 비활성 톤), **스팸 필터**(가입 금지 닉네임), **백업 현황** 텍스트 카드(콘텐츠 수량·미디어 용량·자동 생성 이미지·내보내기 파일·큰 파일), **게시물 내보내기** 독립 카드와 펼침형 전체·연도·월·직접 날짜 범위 작업 요청·목표 ZIP 용량·ZIP당 최대 게시물 수, 작업이 있을 때만 표시되는 **최근 내보내기 작업** 별도 카드(준비 완료 배지 숨김·진행 중 진행도·만료일·파일 체크 선택·전체 선택·선택 파일 다운로드·실패 작업 재시도·실패 상세 오류·작업 삭제), **게시물 가져오기** 독립 카드와 펼침형 ZIP 드롭존·적용 버튼·완료 요약·누락 자산 경고 표시, 진행 중 요청 버튼 잠금 |
|
||||
| lib/signup-blocked-usernames.js | 가입 금지 닉네임 정리·매칭·안내 문구 |
|
||||
| pages/admin/members/index.vue | 관리자 멤버 목록(Ghost형 테이블, 글 목록과 같은 테두리형 검색, 조건 필터, 멤버 추가 버튼, 닉네임+이메일, 등급+비활성 상태, 가입일+최근 활동, IP, 댓글 수) |
|
||||
| pages/admin/members/new.vue | 관리자 멤버 추가(썸네일 URL, 이름, 이메일, 레이블, 관리자 노트) |
|
||||
@@ -225,7 +264,7 @@
|
||||
| pages/post/[slug].vue | 블로그 글 상세, 본문 블로킹 조회 후 완성 화면 진입, 첫 태그가 있을 때만 메타 행에 태그 링크, H1~H3 본문 제목을 오른쪽 TOC 상태로 제공, 공개 회원 로그인 세션의 회원이 글쓴이(`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/tag/[slug].vue | 태그별 글 목록, 존재하지 않는 태그 404, 사이트 설정 태그 게시물 표시개수 기준 서버 태그 필터·공용 번호형 페이지네이션, 태그 헤더 이미지가 있으면 상단 이미지 헤더 표시, 없으면 기본 태그명·설명 + 공통 섹션 패딩을 쓰는 리스트형 게시물 카드, 카드 태그 배지와 오른쪽 아래 화살표 링크 |
|
||||
| pages/pages/[slug].vue | 고정 페이지 상세, HTML 문서 모드는 직접 진입 시 서버 미들웨어 원문 응답·클라이언트 내부 이동 시 현재 URL reload로 서버 원문 응답 재진입 |
|
||||
| pages/signup.vue | 회원가입 3단계, `emailOtpConfigured`일 때 이메일 OTP·인증번호 받기, 모바일 OTP 입력창 높이 보정, `POST /api/auth/email-otp/request` |
|
||||
| pages/signin.vue | 로그인, `/forgot-password` 링크 |
|
||||
@@ -236,7 +275,7 @@
|
||||
|
||||
| 파일 | 기능 |
|
||||
|------|------|
|
||||
| server/api/posts.get.js | 공개 게시물 목록 API(`published`, VIP 이상 등급 시 `members`, `limit`·`tag`·`featured`·`paginated` 조회 옵션) |
|
||||
| server/api/posts.get.js | 공개 게시물 목록 API(`published`, VIP 이상 등급 시 `members`, 기본 개수 상한, 본문 제외 요약 응답, `limit`·`tag`·`featured`·`paginated` 조회 옵션) |
|
||||
| server/api/posts/[slug].get.js | 공개 게시물 상세 API(`published`, VIP 이상 등급 시 `members`) |
|
||||
| server/api/pages.get.js | 공개 고정 페이지 목록 API(`published`만, `listed=1`·섹션별 `limit` 조회 옵션) |
|
||||
| server/api/pages/[slug].get.js | 공개 고정 페이지 상세 API(`published`만) |
|
||||
@@ -245,6 +284,7 @@
|
||||
| server/api/search.get.js | 통합 검색 API(`q` 쿼리, 게시물·페이지 `search_text` 인덱스 기반) |
|
||||
| server/api/site-settings.get.js | 공개 사이트 설정 API |
|
||||
| server/api/homepage-widget.get.js | gethomepage customapi용 당일·7일·30일·180일·365일·누적·콘텐츠 통계 위젯 API |
|
||||
| server/api/csp-report.post.js | 32KB·JSON 계열 형식·IP 해시 빈도 제한과 민감 URL 최소화를 적용한 CSP 위반 204 수집 API |
|
||||
| server/repositories/blog-statistics-repository.js | 공개 게시글·댓글·페이지·태그·회원·누적 방문 통계 집계 |
|
||||
| server/routes/admin/api/posts/[id]/featured.put.js | 관리자 글 목록 추천 상태 전용 수정 API |
|
||||
| server/api/navigation.get.js | 공개 네비게이션 API |
|
||||
@@ -255,7 +295,7 @@
|
||||
| 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/login.post.js | 계정·IP 실패 횟수 제한을 적용한 회원 로그인 API |
|
||||
| server/api/auth/me.get.js | 회원 세션 조회 API(`isAdmin`, `role` 포함) |
|
||||
| server/api/auth/logout.post.js | 회원 로그아웃 API |
|
||||
| server/api/auth/profile.get.js | 회원 프로필 조회 API |
|
||||
@@ -265,10 +305,10 @@
|
||||
| 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/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 | 계정·IP 실패 횟수 제한을 적용한 관리자 로그인 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, 기본 배열 응답과 `paged=true` 페이지 응답 지원 |
|
||||
@@ -298,9 +338,10 @@
|
||||
| server/routes/admin/api/media.put.js | 관리자 미디어 파일명 변경 및 단일/복수 폴더 변경 API |
|
||||
| server/routes/admin/api/media.delete.js | 관리자 미디어 삭제 API |
|
||||
| server/routes/admin/api/media/thumbnail.post.js | 원본 이미지의 게시물 목록 카드·본문 표시·Pages 커버 썸네일 생성·재생성 API |
|
||||
| server/routes/admin/api/media/reconcile.post.js | 파일을 변경하지 않고 카탈로그 upsert·참조 백필·누락 파일 `missing` 표시를 수행하는 관리자 수동 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(이미지·비디오·오디오·문서, 사이트 설정 1회 파일 수·총량 제한, Unicode 원본명 기반 파일명·충돌 시 넘버링, `/uploads/posts` 저장, 성공 시 `media_metadata`를 `미분류`로 기록) |
|
||||
| server/routes/admin/api/uploads.post.js | 관리자 게시물·페이지용 다중 미디어 원본 업로드 API(임시 디스크 스트리밍, 수신 중 파일 수·종류별/전체 용량 제한, Unicode 원본명 기반 hard link 배타 이동·충돌 시 넘버링, 실패 파일 정리, `/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 |
|
||||
@@ -309,6 +350,7 @@
|
||||
| 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.patch.js | 관리자 사이트 설정 허용 필드 검증·부분 수정 API |
|
||||
| server/routes/admin/api/settings/backup-summary.get.js | 관리자 사이트 용량 API(콘텐츠 수량 DB 집계, `public/uploads` 파일 용량 스캔) |
|
||||
| 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 반환) |
|
||||
@@ -319,6 +361,7 @@
|
||||
| server/routes/admin/api/navigation/[id]/favicon-refresh.post.js | 추천 사이트 파비콘 수동 갱신 API |
|
||||
| server/utils/recommended-site-favicon.js | 추천 사이트 파비콘 fetch·`/uploads/system/recommended-favicon-*.png` 저장·일괄 갱신 |
|
||||
| server/plugins/recommended-favicon-cron.js | 매월 1일 03:00(KST) 추천 사이트 파비콘 자동 갱신 |
|
||||
| server/plugins/post-export-worker.js | 서버 시작·30초 주기 게시물 Export 대기/중단 작업 복구 실행 |
|
||||
| scripts/refresh-recommended-favicons.js | 추천 사이트 파비콘 수동 일괄 갱신 CLI(`npm run navigation:refresh-recommended-favicons`) |
|
||||
| server/routes/admin/api/members.get.js | 관리자 멤버 목록 API |
|
||||
| server/routes/admin/api/members.post.js | 관리자 멤버 생성 API |
|
||||
@@ -329,9 +372,10 @@
|
||||
| server/routes/admin/api/members/[id]/ownership-transfer.post.js | 소유자 권한 이전 API(대상→소유자, 요청자→관리자) |
|
||||
| server/utils/content-schema.js | Zod 콘텐츠 스키마 |
|
||||
| server/utils/sample-content.js | 샘플 콘텐츠 저장소 |
|
||||
| server/utils/admin-auth.js | 관리자 세션 쿠키 인증 유틸리티 |
|
||||
| server/utils/admin-auth.js | DB 세션 버전을 포함한 관리자 세션 쿠키 인증 유틸리티 |
|
||||
| server/utils/analytics-admin-exclusion.js | 관리자 세션 요청의 공개 통계 수집 제외 판별 |
|
||||
| server/utils/member-auth.js | 회원 세션 쿠키 인증 유틸리티 |
|
||||
| server/utils/member-auth.js | DB 세션 버전 검증을 포함한 회원 세션 쿠키 인증 유틸리티 |
|
||||
| server/utils/login-attempt-limit.js | 회원·관리자 로그인 계정·IP별 15분 실패 횟수 제한 유틸리티 |
|
||||
| server/utils/request-ip.js | 프록시 헤더 포함 요청 IP 조회 유틸리티 |
|
||||
| server/utils/member-avatar.js | 회원 전용 썸네일 경로 검증·프로필 분리 시 `media_metadata`만 제거(디스크는 관리자 미디어에서 정리) |
|
||||
| server/utils/member-avatar-upload.js | 회원 썸네일 공통 업로드 검증·Unicode 원본명 기반 파일명·WebP 변환·중앙 1:1 크롭·저장 유틸 |
|
||||
@@ -346,18 +390,20 @@
|
||||
| server/utils/media-library.js | 업로드 미디어·Unicode 파일명 정리·논리 폴더(`미분류`, 예약 `썸네일`)·`avatarOwner` 부착·아바타 삭제/이름변경 차단·게시물 카드·본문·Pages 커버 썸네일 사용처 연결 |
|
||||
| server/repositories/postgres-client.js | PostgreSQL 클라이언트 |
|
||||
| server/repositories/content-repository.js | 콘텐츠 조회 저장소 |
|
||||
| server/repositories/post-export-repository.js | 게시물 Export 작업·분할 파일 계획·ZIP 생성 워커 저장소 |
|
||||
| server/repositories/post-import-repository.js | 게시물 Export ZIP Import 저장소(frontmatter·자산 재매핑·게시물 생성) |
|
||||
| server/repositories/post-export-repository.js | 게시물 Export 작업·분할 파일 계획·원본 자산 store 방식 스트리밍 ZIP 생성, PostgreSQL advisory lock 기반 다중 인스턴스 단일 worker 저장소 |
|
||||
| server/repositories/post-import-repository.js | 게시물 Export ZIP Import 저장소(frontmatter 제한 읽기·자산 엔트리 스트리밍·URL 재매핑·게시물 생성) |
|
||||
| server/repositories/member-repository.js | 회원 조회/생성 저장소 |
|
||||
| server/repositories/comment-repository.js | 댓글 조회/생성 저장소 |
|
||||
| server/repositories/comment-repository.js | 댓글 조회/생성/좋아요 저장소, 공개·멤버십 게시물 접근 조건 통합 |
|
||||
| server/repositories/analytics-repository.js | 방문·게시물·페이지·유입 통계 집계·관리자 요약/날짜 상세 조회·방문자 해시 보관 정리 |
|
||||
| server/utils/analytics-pageview-input.js | `POST /api/analytics/pageview` 검증·관리자 세션 제외·기록 |
|
||||
| server/utils/analytics-pageview-input.js | `POST /api/analytics/pageview` 검증·관리자 세션 제외·IP 해시 분당 상한·기록 |
|
||||
| server/utils/adsense-report.js | AdSense OAuth access token 발급·보고서 조회·대시보드 요약 생성 |
|
||||
| server/utils/zip-writer.js | 게시물 Export ZIP 생성 유틸리티 |
|
||||
| server/utils/zip-reader.js | 게시물 Import ZIP 읽기 유틸리티 |
|
||||
| server/utils/zip-writer.js | `archiver` 기반 게시물 Export ZIP 디스크 스트리밍 생성 유틸리티 |
|
||||
| server/utils/zip-reader.js | `unzipper` 기반 게시물 Import ZIP 중앙 디렉터리·엔트리 제한 검증 및 스트림 유틸리티 |
|
||||
| server/utils/multipart-file-upload.js | `busboy` 기반 단일·다중 multipart 파일 수·개별/전체 용량 제한과 임시 디스크 스트리밍 유틸리티 |
|
||||
| server/api/analytics/pageview.post.js | 공개 통계 수집 API |
|
||||
| server/api/analytics/heartbeat.post.js | 공개 heartbeat·체류·스크롤 수집 API |
|
||||
| server/utils/analytics-heartbeat-input.js | heartbeat 검증·관리자 세션 제외·기록 |
|
||||
| server/utils/analytics-heartbeat-input.js | heartbeat 검증·관리자 세션 제외·IP 해시 분당 상한·기록 |
|
||||
| server/utils/analytics-request-limit.js | 공개 통계 pageview·heartbeat 인메모리 IP 해시 윈도 제한 |
|
||||
| server/routes/admin/api/analytics/summary.get.js | 관리자 통계 요약 API |
|
||||
| server/routes/admin/api/analytics/posts.get.js | 관리자 인기 게시물 API |
|
||||
| server/routes/admin/api/analytics/posts/[id].get.js | 관리자 게시물별 통계 API |
|
||||
@@ -418,7 +464,7 @@
|
||||
|
||||
| 파일 | 기능 |
|
||||
|------|------|
|
||||
| package.json | Nuxt 실행 스크립트와 의존성 |
|
||||
| package.json | Nuxt 실행·문법 검사·Node 회귀 테스트·전체 verify 스크립트와 의존성 |
|
||||
| nuxt.config.js | Nuxt 앱 설정, `tailwindcss.cssPath`로 `main.css` 단일 엔트리, Tailwind 모듈, 관리자 QA를 위한 개발 도구 비활성화, 회원 썸네일 최소/최대 해상도·품질 런타임 설정 |
|
||||
| tailwind.config.js | Tailwind 테마 설정 |
|
||||
| assets/css/main.css | 전역 스타일, 공개 배경·사이드바 배경 통일 기준, 관리자 라이트 테마 격리(`admin-layout`), 좌측 사이드바/그리드 전환 애니메이션, 네비게이션 세로 바 hover 효과, 게시물 카드 제목 공통 인터랙션(`post-title-link`), 이동 중 클릭 잠금(`site-navigating`) |
|
||||
@@ -427,9 +473,11 @@
|
||||
| middleware/admin-auth.global.js | 관리자 페이지 접근 인증 |
|
||||
| middleware/pages-html-document.global.js | HTML 문서 모드 고정 페이지(`/pages/:slug`) 클라이언트 소프트 이동을 전체 페이지 이동으로 전환(뒤로가기 잔상 방지) |
|
||||
| scripts/dev-server.js | 로컬 개발 서버 링크 요약 출력 |
|
||||
| scripts/migrate-database.js | 로컬·NAS DB 마이그레이션 적용/상태/baseline 실행 |
|
||||
| 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 운영 이미지 빌드, `.output/server` 기반 앱 런타임과 이미지 백필 스크립트 포함 |
|
||||
| docker-compose.yml | NAS 컨테이너 실행 초안 |
|
||||
| tests/markdown-html-block.test.js | 게시물 HTML sanitizer 공격 우회·허용 HTML 회귀 테스트 |
|
||||
| tests/multipart-file-upload.test.js | 다중 multipart 디스크 스트리밍·파일 크기 제한 회귀 테스트 |
|
||||
| docker-compose.yml | NAS 컨테이너 실행 초안, PostgreSQL 호스트 기본 loopback 바인딩 |
|
||||
|
||||
Reference in New Issue
Block a user