# 기술 명세 ## 현재 아키텍처 - 프런트엔드: 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` - `DELETE /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/custom-items/:itemId` - `DELETE /api/admin/custom-items` - `GET /api/admin/users` - `PATCH /api/admin/users/:userId` - `PATCH /api/admin/users/:userId/password` - `DELETE /api/admin/users/:userId` - `DELETE /api/admin/games/:gameId/items/:itemId` - `DELETE /api/admin/games/:gameId` ## 관리자 화면 메모 - 썸네일은 16:9 비율 미리보기 후 `썸네일 적용` 버튼으로 실제 반영한다. - 게임 기본 아이템 추가는 이름 입력, 파일 선택, 1:1 미리보기 확인 뒤 저장하는 흐름이다. - 아이템 미리보기는 반응형 환경에서도 최대 `192px` 크기 안에서 표시한다. - 게임 전환 또는 업로드 성공 뒤에는 파일 입력값을 초기화해 같은 파일도 다시 선택할 수 있다. - 게임 관리 탭에서는 홈 화면 상단에 먼저 노출할 게임을 최대 50개까지 지정하고, 드래그 또는 위/아래 버튼으로 순서를 저장할 수 있다. - 사용자 업로드 커스텀 아이템은 관리자 화면의 아이템 관리 탭에서 검색, 페이지네이션, 다운로드할 수 있다. - 커스텀 아이템은 사용 횟수(`usageCount`)를 표시하며, 미사용 항목만 필터링해 개별/일괄 삭제할 수 있다. - 관리자 화면에서는 회원 이메일/닉네임/권한 수정, 비밀번호 초기화, 계정 삭제가 가능하다. ## 티어표 접근 메모 - `new` 작성 경로는 로그인한 사용자만 진입할 수 있다. - 비로그인 사용자는 공개된 티어표를 열람만 할 수 있고, 편집 UI와 저장 동작은 비활성화된다. - 커스텀 이미지 추가는 다중 파일 선택과 드래그 앤 드롭을 모두 지원한다. - 티어 행은 기본 5단으로 시작하지만, 사용자가 직접 추가하거나 제거할 수 있다. - 신규 티어표의 공개 여부 기본값은 `ON`이며, 기존 티어표는 편집 화면과 `내 티어표` 목록에서 직접 삭제할 수 있다. - 제목이 비어 있는 상태로 저장하면 내부 제목은 `이름 없음 + 날짜` 형식으로 자동 생성한다. - 제목 입력이 비어 있는 동안에는 무분별한 도배 방지를 위한 관리자 임의 삭제 가능성 안내 문구를 표시한다. - 공개 티어표 목록과 `내 티어표` 목록은 제목 옆에 작성자 아바타와 표시명을 함께 보여준다. - 작성자 아바타 이미지가 없을 경우 목록 썸네일 fallback은 닉네임이 아니라 계정명 기준 첫 글자를 사용한다. - 티어표 목록 메타 정보는 최종 업데이트 시각만 간략하게 표시한다. - 저장 성공 시에는 에디터 안에서 반투명 오버레이 기반 확인 모달을 띄우고, PNG export 이미지는 약 `1360px` 폭과 `pixelRatio 1.5`, 외곽 여백, 작성자/날짜 하단 메타를 포함해 생성한다. - 홈 게임 목록은 관리자 상단 고정 순서가 있으면 그 순서를 먼저 적용하고, 그 외 게임은 최근 생성순으로 뒤에 이어진다. - `커스텀 티어표 만들기`는 카드가 아니라 홈 우측 상단 버튼으로 진입한다. ## 업로드 제한 메모 - 프로필 아바타 업로드는 파일당 최대 `3MB`다. - 관리자 게임 썸네일/기본 아이템 업로드와 사용자 커스텀 이미지 업로드는 파일당 최대 `6MB`다. - 현재는 업로드 전에 이미지 리사이즈/압축을 하지 않고 원본 파일을 그대로 저장한다. ## 운영 환경 변수 - 프런트엔드 - `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은 제거되었다.