관리자 기능과 태그 표시 설정 추가

This commit is contained in:
2026-05-01 18:00:22 +09:00
parent 237eb2990f
commit 787747aa7f
51 changed files with 2261 additions and 128 deletions

View File

@@ -19,6 +19,7 @@
- Vue 컴포넌트 파일: PascalCase
- CSS 클래스: kebab-case
- 고유 클래스명 필수 (Tailwind 외)
- Nuxt 컴포넌트 자동 import는 경로 prefix 없이 파일명 기준으로 사용
## 스타일

View File

@@ -1,6 +1,6 @@
# 배포 가이드
> 현재 프로젝트는 Nuxt 3 초기 스캐폴딩 상태다. Docker 설정은 초안이며 운영 DB 확정 후 NAS에서 검증한다.
> 현재 프로젝트는 Nuxt 3 초기 스캐폴딩 상태다. Docker 설정은 파일 기준 초안이 있으며 운영 DB 확정 후 NAS에서 검증한다.
## 빌드 유형
@@ -15,7 +15,7 @@
### 필수 조건
- Node.js 20+ 권장
- Node.js 22 LTS 권장
- npm 9+
- 개발 DB
@@ -42,6 +42,27 @@ openssl rand -hex 32
npm run dev
```
### 로컬 개발 DB
로컬 개발 DB는 Docker Compose의 `sori-studio-db` 서비스만 실행한다.
```bash
# Docker daemon 시작
colima start
# 개발 DB 컨테이너 실행
ENV_FILE=.env.development docker compose --env-file .env.development up -d sori-studio-db
# 개발 DB 마이그레이션 실행
npm run db:migrate:dev
# DB 준비 상태 확인
docker exec sori-studio-db pg_isready -U sori_studio -d sori_studio
# 시드 데이터 확인
docker exec sori-studio-db psql -U sori_studio -d sori_studio -c 'SELECT count(*) AS posts_count FROM posts;'
```
### 확인 주소
- 개발 서버: http://127.0.0.1:43117
@@ -51,7 +72,7 @@ npm run dev
## UGREEN NAS Docker 배포
> Dockerfile과 docker-compose 설정은 아직 작성 전이다.
> Dockerfile과 docker-compose 설정은 초안이며 NAS 운영 환경에서는 아직 검증 전이다.
### SSH 접속
@@ -114,6 +135,8 @@ docker run -d -p 3000:3000 sori.studio:latest
- 운영 DB는 로컬 개발 서버에서 직접 연결하지 않음
- 관리 도구: CloudBeaver 등으로 추후 연결 가능하게 설계
- NAS Docker 배포 시 PostgreSQL 초기 스키마는 `db/migrations/`의 SQL로 생성
- 로컬 개발 Docker Compose 실행 시 `ENV_FILE=.env.development``--env-file .env.development`를 함께 사용
- 로컬 개발 DB 마이그레이션은 `npm run db:migrate:dev`로 실행
## 사용자 액션 필요 항목

View File

@@ -1,5 +1,35 @@
# 의사결정 이력
## 2026-05-01 v0.0.7
### 관리자 글 작성/수정 구조 결정
관리자 글 작성과 수정은 `AdminPostForm` 단일 컴포넌트를 공유한다. 현재 단계에서는 별도 위지윅 편집기를 도입하지 않고 마크다운 textarea 입력을 먼저 저장 가능한 형태로 연결한다. 글 관리의 핵심 흐름인 생성, 수정, 상태 변경을 먼저 검증한 뒤 미리보기, 자동 저장, 이미지 업로드를 분리해 확장하기 위해서다.
발행/초안/비공개 전환은 별도 publish API가 아니라 게시물 수정 API의 `status` 값으로 처리한다. 초기 관리자에서는 버튼과 API를 늘리기보다 저장 모델을 단순하게 유지하고, 추후 목록에서 빠른 발행 전환이 필요해질 때 별도 액션 API를 추가한다.
### 관리자 태그 관리 방식 결정
태그 관리는 목록 화면에서 생성/수정 입력을 인라인으로 열지 않고 생성/수정 전용 페이지로 분리한다. 태그에 표시 순서와 색상 코드가 추가되면서 입력 항목이 늘었고, 목록 행 안에서 수정 폼을 열면 테이블 레이아웃이 흔들리기 때문이다.
태그 삭제 시 게시물 자체는 삭제하지 않고 `post_tags` 연결만 외래 키 규칙으로 정리한다. 태그는 분류 메타데이터이고 게시물 본문 데이터와 생명주기가 다르기 때문이다.
태그의 `sort_order`는 공개 화면 카테고리 정렬 기준으로 사용하고, `color`는 태그 옆 색상 바와 이후 태그 배지 배경색에 사용할 수 있도록 `#RRGGBB` 문자열로 저장한다.
### 초기 관리자 인증 방식 결정
관리자 기능 1차 구현은 별도 사용자 테이블을 만들지 않고 `ADMIN_EMAIL`, `ADMIN_PASSWORD` 환경 변수로 시작한다. 개인 블로그/CMS 초기 단계에서는 운영 계정 수가 하나이고, 데이터 모델을 먼저 늘리기보다 글 관리 흐름을 빠르게 검증하는 편이 유지보수에 유리하다.
로그인 성공 시 `/admin` 경로에만 적용되는 httpOnly 세션 쿠키를 설정한다. 세션 토큰은 `ADMIN_PASSWORD` 기반 HMAC 서명으로 검증해 쿠키 위조를 막고, 운영 단계에서 사용자 테이블이나 더 강한 인증 방식이 필요해지는 시점에 확장한다.
### 로컬 개발 컨테이너 실행 환경 결정
새 개발 환경에서 Docker Desktop 없이 터미널 중심으로 PostgreSQL 개발 DB를 실행하기 위해 Homebrew, Docker CLI, Docker Compose, Colima 조합을 사용한다. 이 방식은 Docker daemon을 Colima가 담당하고, 프로젝트는 기존 `docker-compose.yml`을 그대로 활용할 수 있어 NAS Docker 배포 구조와 로컬 개발 구조를 크게 벌리지 않는다.
로컬 개발 DB는 `.env.development`만 사용하고, Docker Compose 실행 시 `ENV_FILE=.env.development``--env-file .env.development`를 함께 넘긴다. 이렇게 하면 Git에 포함되지 않는 로컬 비밀번호를 사용하면서도 운영 기본값인 `.env.production` 기준은 유지할 수 있다.
개발 DB 마이그레이션은 `npm run db:migrate:dev`로 실행한다. Docker entrypoint는 새 볼륨 생성 시에만 SQL을 자동 실행하므로, 이미 생성된 개발 DB에도 반복 적용할 수 있는 별도 실행 명령을 둔다.
## 2026-04-29 v0.0.6
### 환경 변수 파일 보안 기준 정리

View File

@@ -22,6 +22,13 @@
| components/site/PostCard.vue | 목록의 게시물 카드 |
| components/site/TagHeader.vue | 태그 페이지 헤더 |
## 관리자 컴포넌트
| 파일 | 화면 위치 |
|------|-----------|
| components/admin/AdminPostForm.vue | 관리자 글 작성/수정 폼 |
| components/admin/AdminTagForm.vue | 관리자 태그 생성/수정 폼 |
## 콘텐츠 컴포넌트
| 파일 | 화면 위치 |
@@ -46,11 +53,14 @@
| 파일 | 화면 |
|------|------|
| pages/admin/index.vue | 대시보드 |
| pages/admin/login.vue | 관리자 로그인 |
| pages/admin/posts/index.vue | 글 목록 |
| pages/admin/posts/new.vue | 글 작성 |
| pages/admin/posts/[id].vue | 글 수정 |
| pages/admin/pages/index.vue | 페이지 목록 |
| pages/admin/tags/index.vue | 태그 관리 |
| pages/admin/tags/new.vue | 태그 생성 |
| pages/admin/tags/[id].vue | 태그 수정 |
| pages/admin/settings/index.vue | 사이트 설정 |
## 공개 페이지
@@ -71,8 +81,24 @@
| server/api/pages.get.js | 고정 페이지 목록 샘플 API |
| server/api/pages/[slug].get.js | 고정 페이지 상세 샘플 API |
| server/api/tags.get.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/tags.get.js | 관리자 태그 목록 API |
| 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/utils/content-schema.js | Zod 콘텐츠 스키마 |
| server/utils/sample-content.js | 샘플 콘텐츠 저장소 |
| server/utils/admin-auth.js | 관리자 세션 쿠키 인증 유틸리티 |
| server/utils/admin-post-input.js | 관리자 게시물 입력값 검증 스키마 |
| server/utils/admin-tag-input.js | 관리자 태그 입력값 검증 스키마 |
| server/repositories/postgres-client.js | PostgreSQL 클라이언트 |
| server/repositories/content-repository.js | 콘텐츠 조회 저장소 |
@@ -82,6 +108,7 @@
|------|------|
| db/migrations/001_initial_schema.sql | PostgreSQL 초기 테이블 스키마 |
| db/migrations/002_seed_development.sql | 개발용 샘플 데이터 |
| db/migrations/003_add_tag_display_fields.sql | 태그 표시 순서와 색상 필드 추가 |
## 설정/배포
@@ -92,6 +119,8 @@
| tailwind.config.js | Tailwind 테마 설정 |
| assets/css/main.css | 전역 스타일 |
| composables/useMenuState.js | 좌측 메뉴 열림 상태 관리 |
| middleware/admin-auth.global.js | 관리자 페이지 접근 인증 |
| scripts/migrate-development-db.js | 로컬 개발 DB 마이그레이션 실행 |
| .env.example | 환경 변수 예시 |
| Dockerfile | NAS 운영 이미지 빌드 |
| docker-compose.yml | NAS 컨테이너 실행 초안 |

View File

@@ -141,6 +141,8 @@ components/content/
| name | String | 태그명 |
| slug | String | URL 슬러그 |
| description | String | 설명 |
| sort_order | Integer | 사용자 화면 표시 순서 |
| color | String | 태그 색상 코드 |
| created_at | DateTime | 생성일 |
| updated_at | DateTime | 수정일 |
@@ -179,15 +181,31 @@ components/content/
### 관리자 API (`/admin/api/`)
- `POST /admin/api/auth/login` - 로그인
- `POST /admin/api/auth/logout` - 로그아웃
- `GET /admin/api/auth/me` - 현재 관리자 세션 조회
- `GET /admin/api/posts` - 글 목록
- `POST /admin/api/posts` - 글 작성
- `GET /admin/api/posts/:id` - 글 상세
- `PUT /admin/api/posts/:id` - 글 수정
- `DELETE /admin/api/posts/:id` - 글 삭제
- `POST /admin/api/posts/:id/publish` - 글 발행
- `GET /admin/api/tags` - 태그 목록
- `POST /admin/api/tags` - 태그 생성
- `GET /admin/api/tags/:id` - 태그 상세
- `PUT /admin/api/tags/:id` - 태그 수정
- `DELETE /admin/api/tags/:id` - 태그 삭제
> 글 발행/초안/비공개 전환은 현재 `PUT /admin/api/posts/:id`의 `status` 값으로 처리한다.
> 태그 삭제 시 `post_tags` 연결도 데이터베이스 외래 키 규칙에 따라 함께 삭제된다.
> 태그 목록은 `sort_order ASC, name ASC` 기준으로 정렬한다.
> 태그 `color`는 `#RRGGBB` 형식이며 사용자 화면 태그 색상 표시와 배지 배경색에 사용한다.
### 관리자 인증
- 초기 관리자 인증은 `ADMIN_EMAIL`, `ADMIN_PASSWORD` 환경 변수를 사용
- 로그인 성공 시 httpOnly 세션 쿠키를 `/admin` 경로에 설정
- 관리자 페이지 접근은 `/admin/api/auth/me` 확인 후 허용
- 세션 토큰은 `ADMIN_PASSWORD` 기반 HMAC 서명으로 검증
---
## 미디어 관리

View File

@@ -2,11 +2,7 @@
## 1차 관리자 개발
- [ ] 로그인 기능 구현
- [ ] 글 목록 조회
- [ ] 글 작성/수정 (마크다운 에디터)
- [ ] 글 발행/비공개 전환
- [ ] 태그 관리 (생성/수정/삭제)
- [ ] 마크다운 에디터 미리보기 및 편집 편의 기능 고도화
- [ ] 이미지 업로드
## 2차 관리자 개발
@@ -29,9 +25,6 @@
- [ ] 공개 화면 모바일 사이드바/네비게이션 방식 결정
- [ ] Thred 참고 화면 기준 시각 QA
- [ ] 사이드바 토글 애니메이션 세부 조정
- [ ] 게시물 카드 실제 데이터 연동
- [ ] 태그 페이지 실제 데이터 연동
- [ ] 고정 페이지 실제 데이터 연동
## 콘텐츠 스타일 구현
@@ -51,8 +44,6 @@
## 데이터베이스
- [ ] PostgreSQL 마이그레이션 실행 스크립트 작성
- [ ] 로컬 개발 DB 컨테이너 실행 가이드 작성
- [ ] NAS 운영 DB 연결 설정 실제 값 작성
- [ ] 개발 DB와 운영 DB 분리 검증 절차 작성
- [ ] CloudBeaver PostgreSQL 연결 방식 확정

View File

@@ -1,5 +1,44 @@
# 업데이트 이력
## v0.0.7
- 태그 정렬 순서와 색상 코드 필드 추가.
- 태그 표시 필드 마이그레이션 추가.
- 관리자 태그 생성/수정 화면을 개별 페이지로 분리.
- 관리자 태그 목록 화면의 인라인 수정 제거.
- 공개 좌측 사이드바 카테고리를 실제 태그 색상과 정렬 순서 기준으로 연결.
- 관리자 태그 상세 조회 API 추가.
- 관리자 태그 목록 API 추가.
- 관리자 태그 생성 API 추가.
- 관리자 태그 수정 API 추가.
- 관리자 태그 삭제 API 추가.
- 관리자 태그 관리 화면을 실제 API에 연결.
- 관리자 글 삭제 API 추가.
- 관리자 글 목록과 수정 화면에 삭제 액션 추가.
- 관리자 글 작성 API 추가.
- 관리자 글 상세 조회 API 추가.
- 관리자 글 수정 API 추가.
- 관리자 글 작성/수정 공통 폼 추가.
- 관리자 새 글 작성 화면과 수정 화면을 실제 저장 API에 연결.
- 관리자 글 상태를 초안/발행/비공개로 저장할 수 있도록 수정.
- 관리자 접근 미들웨어의 서버 인증 확인 방식 수정.
- 환경 변수 기반 관리자 로그인 기능 추가.
- 관리자 세션 쿠키 인증 유틸리티 추가.
- 관리자 로그아웃 및 세션 조회 API 추가.
- 관리자 글 목록 API와 화면 연결.
- 개발 서버의 `#app-manifest` 가상 모듈 분석 오류를 피하도록 Nuxt app manifest 실험 기능 비활성화.
- Nuxt 컴포넌트 자동 import 설정을 문서의 컴포넌트명 기준에 맞게 수정.
- 홈, 태그, 게시물, 고정 페이지 공개 화면을 실제 API 데이터에 연결.
- 로컬 PostgreSQL 마이그레이션 실행 스크립트 추가.
- 개발 DB 마이그레이션 npm 명령 추가.
- Homebrew, Docker CLI, Docker Compose, Colima 기반 로컬 컨테이너 실행 환경 구성.
- Docker Compose가 `ENV_FILE` 값으로 로컬/운영 환경 파일을 선택할 수 있도록 수정.
- 로컬 PostgreSQL 개발 DB 컨테이너 실행 및 시드 데이터 확인.
- Nuxt 개발/프리뷰 스크립트가 `.env.development`를 명시적으로 읽도록 수정.
- 새 개발 환경에서 Node.js 22 LTS 기준 의존성 설치 및 빌드 검증.
- 로컬 개발 필수 조건 문서의 Node.js 권장 버전 정리.
- 패키지 버전을 0.0.7로 갱신.
## v0.0.6
- `.env.example`의 실제 계정/비밀번호 값을 예시 전용 placeholder로 교체.