121 lines
4.1 KiB
Markdown
121 lines
4.1 KiB
Markdown
# 기술 명세
|
|
|
|
## 현재 아키텍처
|
|
- 프런트엔드: Vue 3 + Vite + Pinia + Vue Router
|
|
- 백엔드: Express 5
|
|
- 데이터 저장소: MariaDB(MySQL 호환)
|
|
- 세션 저장소: `session-file-store` 기반 파일 세션
|
|
- 업로드 저장소: 로컬 파일 시스템(`backend/uploads/`)
|
|
|
|
## 데이터 저장 구조
|
|
- 메인 데이터베이스: MariaDB `tier_cursor` (기본값)
|
|
- 세션 파일: `backend/.sessions/*.json`
|
|
- 업로드 파일:
|
|
- 게임 이미지: `backend/uploads/games/`
|
|
- 아바타: `backend/uploads/avatars/`
|
|
- 커스텀 아이템: `backend/uploads/custom/`
|
|
- 시드 이미지: `backend/uploads/seeds/`
|
|
|
|
## DB 스키마
|
|
- `users`
|
|
- `id`: string
|
|
- `email`: string
|
|
- `nickname`: string
|
|
- `passwordHash`: string
|
|
- `isAdmin`: boolean
|
|
- `avatarSrc`: string
|
|
- `createdAt`: number
|
|
- `games`
|
|
- `id`: string
|
|
- `name`: string
|
|
- `thumbnailSrc`: string
|
|
- `createdAt`: number
|
|
- 시스템 전용 `freeform` 레코드는 홈 화면의 `직접 티어표 만들기` 저장 대상이며 일반 게임 목록에서는 숨긴다.
|
|
- `gameItems`
|
|
- `id`: string
|
|
- `gameId`: string
|
|
- `src`: string
|
|
- `label`: string
|
|
- `createdAt`: number
|
|
- `customItems`
|
|
- `id`: string
|
|
- `ownerId`: string
|
|
- `src`: string
|
|
- `label`: string
|
|
- `createdAt`: number
|
|
- `tierLists`
|
|
- `id`: string
|
|
- `authorId`: string
|
|
- `gameId`: string
|
|
- `title`: string
|
|
- `description`: string
|
|
- `isPublic`: boolean
|
|
- `groups`: `{ id, name, itemIds[] }[]`
|
|
- `pool`: `{ id, src, label, origin }[]`
|
|
- `createdAt`: number
|
|
- `updatedAt`: number
|
|
- `gameSuggestions`
|
|
- `id`: string
|
|
- `name`: string
|
|
- `createdAt`: number
|
|
|
|
## 주요 API
|
|
- 인증
|
|
- `POST /api/auth/signup`
|
|
- `POST /api/auth/login`
|
|
- `POST /api/auth/logout`
|
|
- `GET /api/auth/me`
|
|
- `GET /api/auth/meta`
|
|
- `POST /api/auth/profile`
|
|
- 게임
|
|
- `GET /api/games`
|
|
- `GET /api/games/:gameId`
|
|
- 티어표
|
|
- `GET /api/tierlists/public`
|
|
- `GET /api/tierlists/me`
|
|
- `GET /api/tierlists/:id`
|
|
- `POST /api/tierlists/custom-items`
|
|
- `POST /api/tierlists`
|
|
- 관리자
|
|
- `POST /api/admin/games`
|
|
- `POST /api/admin/games/:gameId/thumbnail`
|
|
- `POST /api/admin/games/:gameId/images`
|
|
- `GET /api/admin/custom-items`
|
|
- `DELETE /api/admin/games/:gameId/items/:itemId`
|
|
- `DELETE /api/admin/games/:gameId`
|
|
|
|
## 관리자 화면 메모
|
|
- 썸네일은 16:9 비율 미리보기 후 `썸네일 적용` 버튼으로 실제 반영한다.
|
|
- 아이템 추가는 이름 입력, 파일 선택, 1:1 미리보기 확인 뒤 저장하는 흐름이다.
|
|
- 아이템 미리보기는 반응형 환경에서도 최대 `192px` 크기 안에서 표시한다.
|
|
- 게임 전환 또는 업로드 성공 뒤에는 파일 입력값을 초기화해 같은 파일도 다시 선택할 수 있다.
|
|
- 사용자 업로드 커스텀 아이템은 관리자 화면 하단 검토 영역에서 목록/다운로드할 수 있다.
|
|
|
|
## 운영 환경 변수
|
|
- 프런트엔드
|
|
- `VITE_API_ORIGIN`: API 및 업로드 파일 절대 기준 주소
|
|
- 백엔드
|
|
- `DB_HOST`: MariaDB 호스트
|
|
- `DB_PORT`: MariaDB 포트
|
|
- `DB_USER`: MariaDB 계정
|
|
- `DB_PASSWORD`: MariaDB 비밀번호
|
|
- `DB_NAME`: 데이터베이스명
|
|
- `PORT`: 서버 포트
|
|
- `SESSION_SECRET`: 세션 서명 키
|
|
- `CORS_ORIGINS`: 허용할 프런트 도메인 목록(쉼표 구분)
|
|
- `TRUST_PROXY`: 프록시 홉 수
|
|
- `SESSION_COOKIE_SECURE`: `true`면 HTTPS 전용 쿠키
|
|
- `SESSION_COOKIE_SAME_SITE`: 기본 `lax`
|
|
|
|
## NAS 배포 메모
|
|
- 현재 구조는 MariaDB/MySQL 계열이므로 NAS에 MariaDB를 올리면 phpMyAdmin 또는 Adminer로 직접 데이터 확인이 가능하다.
|
|
- 추천 구성:
|
|
- MariaDB 컨테이너 또는 NAS 패키지 설치
|
|
- phpMyAdmin 또는 Adminer 설치
|
|
- 앱은 환경변수로 해당 DB에 연결
|
|
|
|
## 로컬 개발 기준
|
|
- 기본 로컬 개발도 `docker compose`로 띄운 MariaDB를 사용한다.
|
|
- 기본 백엔드 실행 스크립트 `backend/package.json`의 `dev`, `start`는 로컬 MariaDB(`127.0.0.1:3307`) 기준으로 맞춰져 있다.
|
|
- `backend/src/db.js`는 MariaDB만 대상으로 동작하며, 파일 기반 fallback은 제거되었다.
|