Files
tier-maker/docs/history.md

15 KiB

의사결정 이력

2026-03-26 v0.1.41

  • 관리자 커스텀 아이템 승격은 버튼만 보이는 상태로 끝나면 안 되므로, 프런트 API와 백엔드 라우트가 실제로 함께 연결되어야 기능이 완결된다고 정리했다.

2026-03-26 v0.1.40

  • 관리자 기본 아이템 이름 저장은 눌러도 변화가 없으면 혼란스러우므로, 실제 변경이 있을 때만 버튼이 활성화되는 편이 더 명확하다고 판단했다.
  • 사용자 커스텀 이미지는 관리자 검토 후 특정 게임의 기본 템플릿으로 복제해 가져올 수 있어야 운영 효율이 높아지므로, 게임 선택 기반 승격 흐름을 추가하기로 결정했다.

2026-03-26 v0.1.39

  • 티어표 편집 헤더는 게임명 kicker보다 제목과 설명이 더 중요하므로, 좌측 입력 중심 구조로 재배치하고 썸네일은 우측 보조 카드로 분리하는 편이 더 자연스럽다고 판단했다.
  • 썸네일 조작 버튼은 모바일에서도 카드와 함께 유지되는 편이 흐름이 덜 끊기므로, 미리보기 아래 별도 줄로 떨어뜨리기보다 카드 내부의 짧은 액션 행으로 묶기로 결정했다.

2026-03-26 v0.1.38

  • 관리자 기본 아이템은 업로드 시점에만 이름을 정할 수 있으면 운영 중 수정이 어려우므로, 목록에서 직접 이름을 바꾸고 저장할 수 있게 하기로 결정했다.
  • 게임별 티어표 목록도 식별성이 중요하므로, 사용자가 편집 시 별도 썸네일을 지정할 수 있게 하고 목록 카드에서는 게임 카드와 비슷한 상단 썸네일 구조를 사용하기로 결정했다.

2026-03-19

  • 초기 저장소는 빠른 구현을 위해 lowdb(JSON 파일)를 채택했다.
  • 인증은 JWT 대신 서버 세션(express-session + session-file-store)을 사용했다.
  • 업로드 파일은 외부 스토리지 없이 로컬 디스크(backend/uploads/)에 저장하기로 했다.

2026-03-19 v0.1.3

  • 배포 환경 호환성을 위해 프런트엔드의 API 기준 주소를 환경변수(VITE_API_ORIGIN)로 통합했다.
  • NAS/리버스 프록시 환경을 고려해 CORS 및 세션 쿠키 옵션을 환경변수 기반으로 전환했다.
  • 파일명 깨짐과 URL 이식성 문제를 줄이기 위해 업로드 파일명을 ASCII 기반으로 생성하도록 변경했다.
  • 게임 이미지 경로는 저장 시 상대 경로(/uploads/...)를 유지하는 방향으로 정리했다.
  • 현재 단계에서는 구조 변경 비용을 고려해 DB를 유지하되, 운영/확장성 요구가 커지기 전 RDB 이관 판단이 필요하다고 기록했다.

2026-03-19 v0.1.4

  • 운영 편의성과 NAS 환경에서의 데이터 조회 필요성 때문에 저장소를 MariaDB(MySQL 호환) 기준으로 전환했다.
  • 관리자 지정 아이템과 사용자 커스텀 이미지는 책임과 수명 주기가 다르므로 별도 테이블(game_items, custom_items)로 분리했다.
  • 작성자 식별성을 위해 공개 티어표에 닉네임을 표시하고, 프로필에서 닉네임을 수정할 수 있게 했다.
  • 아바타 업로드는 즉시 반영보다 “선택 후 저장” 흐름이 맞다고 판단해 미리보기와 실제 저장을 분리했다.
  • 관리자 페이지는 게임 선택 후 상세 관리가 열리는 단계형 흐름으로 바꾸는 것이 실사용에 더 안전하다고 결정했다.

2026-03-19 v0.1.5

  • 로컬 개발과 운영 환경의 차이를 줄이기 위해 기본 로컬 개발 DB도 MariaDB로 고정했다.
  • 로컬 실행 편의를 위해 docker-compose.ymlmariadbphpMyAdmin 서비스를 추가했다.
  • 백엔드 기본 dev/start/migrate 스크립트는 로컬 MariaDB 기준 값으로 정리하고, lowdb는 예외용 fallback 스크립트로만 남겼다.

2026-03-19 v0.1.6

  • 저장소 운영 규칙을 정리하면서 Git 작성자 정보는 프로젝트 기준 계정으로 통일하고, 커밋 메시지는 한국어로 남기기로 결정했다.

2026-03-19 v0.1.7

  • 관리자 페이지는 여러 작업을 동시에 나열하는 구조보다 “하나의 작업 모드를 선택하고 그 작업에 집중하는 구조”가 더 적합하다고 판단해 단계형 UI로 전환했다.
  • 관리자에게는 생성뿐 아니라 삭제 책임도 필요하므로 게임 삭제와 아이템 삭제 기능을 추가하기로 결정했다.
  • 아이템 삭제는 단순 파일/레코드 삭제만으로 끝내면 안 되고, 기존 티어표 데이터의 참조까지 함께 정리해야 한다고 결정했다.

2026-03-19 v0.1.8

  • 관리자 업로드 작업은 선택 즉시 결과를 예측할 수 있어야 하므로, 썸네일과 아이템 모두 “파일 선택 → 미리보기 → 실제 업로드” 흐름으로 보강했다.
  • 게임 썸네일은 대표 이미지 성격이 강하므로 16:9 비율로, 아이템은 캐릭터/오브젝트 단위 식별이 중요하므로 1:1 비율로 보는 방향을 채택했다.
  • 현재 db.json과 lowdb 관련 코드는 기본 운영 런타임이 아니라 마이그레이션/예외 fallback 성격임을 분명히 정리했다.

2026-03-19 v0.1.9

  • 로컬과 운영 환경을 완전히 같은 DB 계층으로 맞추기 위해 lowdb fallback을 제거하고 MariaDB만 지원하는 코드베이스로 정리했다.
  • 마이그레이션 종료 이후에는 레거시 JSON 저장소와 예외 실행 스크립트를 남겨두는 비용이 더 크다고 판단해 삭제하기로 결정했다.

2026-03-19 v0.1.10

  • 관리자 업로드 작업은 "파일 선택 후 적용"이 더 정확하므로, 썸네일 버튼 문구와 활성화 조건을 그 흐름에 맞추기로 결정했다.
  • 작은 화면에서 미리보기가 실제 작업 영역을 압박하지 않도록, 아이템 미리보기는 정사각형을 유지하되 최대 크기를 제한하는 방향을 채택했다.
  • 파일 입력은 업로드 성공 후와 게임 전환 시 초기화해 같은 파일 재선택이 막히지 않도록 정리했다.

2026-03-19 v0.1.11

  • 관리자 화면은 좌우 여백이 크게 남는 구조보다, 상단 2열 작업 카드와 하단 목록 영역으로 나누는 편이 더 안정적이라고 판단해 레이아웃을 재정리했다.
  • 게임 목록에 없는 주제로도 바로 작업할 수 있도록, 시스템 전용 freeform 게임을 내부적으로 유지하고 홈 화면에서는 직접 티어표 만들기 카드로 노출하기로 결정했다.
  • 게임 제안은 현재 운영 흐름과 맞지 않아 사용자 진입점과 프런트 API에서 제거하고, 대신 관리자에게는 사용자 커스텀 아이템 검토 기능을 제공하기로 했다.

2026-03-19 v0.1.12

  • 앱 전체 배경은 화면 폭 전체를 사용하고, 개별 콘텐츠만 필요한 만큼 정렬하는 방향이 더 자연스럽다고 판단해 전역 최대 폭 제한을 제거했다.
  • 비로그인 사용자가 새 티어표를 편집하다 저장 단계에서 막히는 경험은 손실 위험이 크므로, 작성 시작 자체를 로그인 사용자로 제한하고 공개 티어표는 읽기 전용으로 보여주기로 결정했다.
  • 커스텀 이미지 업로드는 단일 파일 선택만으로는 불편하므로, 다중 선택과 드래그 앤 드롭을 기본 흐름으로 보강했다.
  • 관리자에게는 게임 관리뿐 아니라 회원 관리 책임도 필요하므로, 회원 목록 조회/수정/삭제 기능을 추가하기로 결정했다.

2026-03-19 v0.1.13

  • 관리자 페이지는 기능 수가 늘어난 만큼 게임, 아이템, 회원 관리 탭으로 나누는 편이 더 안전하다고 판단했다.
  • 사용자 커스텀 아이템은 수량이 빠르게 커질 수 있으므로, 검색과 페이지네이션을 기본 제공하는 관리 화면으로 보는 방향을 채택했다.
  • 메일 기반 복구가 없으므로, 관리자가 회원 비밀번호를 직접 초기화할 수 있는 기능을 제공하기로 결정했다.
  • 티어표 구조는 게임마다 다르므로, 기본 5단은 시작 템플릿일 뿐 사용자가 행을 직접 추가/삭제할 수 있어야 한다고 결정했다.

2026-03-19 v0.1.17

  • 작성자가 자기 티어표를 직접 삭제할 수 있어야 관리 흐름이 완결되므로, 내 티어표 화면에 삭제 기능을 추가하기로 결정했다.
  • 사용자 커스텀 이미지는 서버 용량을 계속 차지하므로, 참조가 하나도 남지 않은 이미지(미사용 항목)를 식별하고 관리자 화면에서 개별/일괄 정리할 수 있도록 하기로 결정했다.

2026-03-19 v0.1.19

  • 티어표 공개 여부는 운영 기준상 대부분 공개 공유가 목적이므로, 신규 작성 시 기본값을 공개 ON으로 두기로 결정했다.
  • 에디터에서 저장 관련 행동은 좌우로 역할을 나눠 다운로드/삭제공개/저장으로 묶는 편이 더 빠르게 인지된다고 판단했다.
  • 공개 목록과 내 목록에서 제목만으로는 식별이 어려우므로, 제목 옆에 작성자 아바타와 표시명을 함께 노출하기로 결정했다.
  • 티어표 카드 메타 정보는 저장 시각과 업데이트 시각을 동시에 노출하는 대신, 최종 업데이트 시각만 남겨 단순화하기로 결정했다.

2026-03-26 v0.1.21

  • 목록 썸네일 fallback 문자는 닉네임보다 계정 기준이 더 일관되므로, 아바타 이미지가 없을 때는 계정명 첫 글자를 사용하기로 결정했다.
  • 저장 성공은 화면 이동보다 현 위치 유지가 더 중요하므로, 편집을 계속할 수 있는 확인형 모달로 피드백을 제공하기로 결정했다.
  • PNG export는 가장자리 여백이 없는 결과보다 중앙 정렬된 카드형 결과물이 더 완성도 있게 보이므로, export 전용 보드에 충분한 바깥 패딩을 포함하기로 했다.

2026-03-26 v0.1.22

  • 무제목 저장은 게임 이름 기본값보다 이름 없음 + 날짜가 더 명확하다고 판단해 자동 제목 규칙을 변경했다.
  • 제목이 비어 있는 티어표는 품질 관리 대상이 될 수 있으므로, 작성 중 단계에서 관리자 임의 삭제 가능성을 미리 안내하기로 결정했다.
  • 다운로드 이미지에는 편집용 빈 칸 안내 문구를 제외하고, 더 넓은 보드 폭과 하단 작성자/날짜 메타를 포함해 공유용 완성도를 높이기로 결정했다.

2026-03-26 v0.1.23

  • 홈 화면 정렬은 단순 생성순 하나보다 관리자 상단 고정 순서 + 나머지 최신 생성순 조합이 운영과 신규 노출을 함께 만족시킨다고 판단했다.
  • 상단 고정은 전체 수동 정렬보다 최대 50개만 관리하는 방식이 운영 부담이 적으므로, 관리자에게는 제한된 상단 고정 목록만 직접 편집하게 하기로 결정했다.
  • 커스텀 티어표 만들기는 일반 게임 카드와 성격이 다르므로 카드형 목록에서 분리해 우측 상단 버튼으로 노출하기로 결정했다.

2026-03-26 v0.1.24

  • 상단 고정 게임이 50개까지 늘어날 수 있으므로, 위/아래 버튼만으로는 불편하다고 판단해 드래그 정렬을 함께 제공하기로 결정했다.
  • export 결과가 지나치게 넓으면 아이콘이 한 줄에 과도하게 몰리므로, 공유용 이미지 폭을 줄이고 pixel ratio도 낮춰 균형을 맞추기로 결정했다.
  • 현재 업로드는 파일 크기 제한만 있고 서버 저장 전 최적화는 없으므로, 운영 문서에 현황을 명확히 남기고 향후 리사이즈/압축 도입 여부를 검토하기로 했다.

2026-03-26 v0.1.25

  • 저장 결과물 기준 너비가 여전히 길다고 판단해, export 보드 폭을 추가로 960px까지 줄여 최종 PNG 밀도를 더 낮추기로 결정했다.

2026-03-26 v0.1.26

  • 아이콘 크기는 사용자 취향 차이가 큰 요소이므로, 고정값 하나보다 기본 80px에 단계형 크기 선택을 제공하는 편이 더 낫다고 판단했다.

2026-03-26 v0.1.27

  • NAS 운영은 리버스 프록시 설정을 단순하게 유지하는 편이 좋으므로, 프런트 컨테이너 하나만 외부 공개하고 /api, /uploads는 내부 프록시로 넘기는 구조를 채택했다.
  • 운영은 로컬 개발 컴포즈와 분리된 전용 docker-compose.prod.yml을 두고, 환경변수는 .env.production으로 분리해 관리하기로 결정했다.

2026-03-26 v0.1.28

  • UGREEN NAS에서 MariaDB 초기화가 길게 걸릴 수 있으므로, healthcheck는 앱 계정보다 root 기준 ping과 더 긴 유예 시간으로 두는 편이 안전하다고 판단했다.

2026-03-26 v0.1.29

  • NAS에서 HTTPS를 종료한 뒤 내부 컨테이너끼리는 HTTP로 통신하는 구조에서는, 프런트 프록시가 백엔드에 원래 프로토콜을 정확히 전달하지 않으면 secure 세션 쿠키가 발급되지 않는다고 판단했다.
  • 따라서 운영 프런트 Nginx는 백엔드 프록시 요청에 X-Forwarded-Proto: https를 명시하고, Express 세션도 프록시 환경을 명시적으로 신뢰하도록 설정하기로 결정했다.

2026-03-26 v0.1.30

  • 운영 프런트는 다른 origin 절대 URL보다 같은 origin 상대 /api 요청을 우선해야 세션 쿠키 저장이 안정적이라고 판단했다.

2026-03-26 v0.1.31

  • 세션 기반 로그인 응답은 저장소 반영 타이밍 차이를 줄이기 위해 req.session.save()를 명시 호출하는 쪽이 운영 안정성에 유리하다고 판단했다.

2026-03-26 v0.1.32

  • 인증 문제를 빠르게 확인하기 위해 일시적으로 세션 저장 성공/실패 로그를 남기고 원인을 좁혀가는 접근을 선택했다.

2026-03-26 v0.1.33

  • 프록시 환경의 실제 판단 값을 보기 위해 req.secure, req.protocol, x-forwarded-proto를 직접 로그로 비교해 원인을 확인하기로 했다.

2026-03-26 v0.1.34

  • 일부 NAS 환경에서 favicon.svg 정적 응답이 403으로 차단될 수 있으므로, 운영 안정성을 위해 별도 파일 요청이 필요 없는 인라인 데이터 URL 파비콘으로 전환하기로 결정했다.
  • 관리자 기본 아이템 등록은 단일 파일 업로드만으로는 운영 부담이 크므로, 다중 선택과 드래그 앤 드롭을 지원하고 라벨은 파일명으로 자동 생성하는 방향을 채택했다.

2026-03-26 v0.1.35

  • NAS 운영 경로는 수동 파일 복사보다 Git clone 기반이 로컬 개발 흐름과 더 잘 맞고, 실수로 누락되는 파일을 줄일 수 있으므로 기본 배포 방식으로 권장하기로 결정했다.
  • 운영 환경 변수와 Docker 볼륨은 Git 저장소 바깥의 NAS 자산으로 유지하고, 코드는 git pull로만 반영하는 역할 분리를 명확히 하기로 했다.

2026-03-26 v0.1.36

  • 브라우저 탭 제목은 개발용 기본 문자열보다 서비스 이름을 직접 보여주는 편이 맞다고 판단해 Tier Maker로 고정했다.
  • 무제목 티어표 기본값은 날짜형 임시 제목보다 사용자가 어떤 게임으로 작성했는지 즉시 알 수 있는 게임명 기준이 더 자연스럽다고 판단했다.

2026-03-26 v0.1.37

  • 운영 포트 충돌을 피하기 위해 프로덕션 외부 포트는 frontend=18080, phpMyAdmin=18081로 고정하고, 리버스 프록시 문서도 그 기준으로 맞추기로 했다.
  • 인증 장애 원인을 찾기 위한 디버그 로그는 문제 해결 후 제거하고, 실제 운영에는 세션 저장 보강과 프록시 헤더 설정만 유지하는 편이 낫다고 판단했다.