Files
uniare.sori.studio/docs/update.md

651 lines
38 KiB
Markdown

# 업데이트 이력
## 2026-10-24 / v4.0.28 — Re:제로 EX17BT 카드·패러렐 이미지 추가
### 수행 작업
- `ua40` Re:제로 EX17BT 카드 데이터 116건 추가
- EX17BT 카드 이미지 81개 추가
- `ua50` 이누야샤 패러렐 이미지 25개, `ua54` 무직전생 패러렐 이미지 29개 추가
- `ua54` `UAPR/MST-1-054` UR 패러렐 카드 데이터 추가
- `ua57` 슈타인즈 게이트 패러렐 이미지 33개 추가
- VERSION과 API 버전을 v4.0.28로 통일
### 검증
- `ua40` 브라우저 모듈 문법 검증 통과
- EX17BT 116개 판본 중 이미지 81개 존재, 미확보 35개 확인
- 신규 이미지 168개의 Git LFS 추적과 카드 데이터 참조 확인
- CSS 변경이 없어 CSS 빌드 생략
- API 테스트는 로컬 의존성(`bcryptjs`, `express`) 미설치로 실행하지 못함
## 2026-10-12 / v4.0.27 — 슈타인즈 게이트 추가·마도카 이미지 보강
### 수행 작업
- UA57 카드 데이터 128건, 일반 이미지 95개, 한국어·일본어·영어 시리즈명 추가
- 마도카 EX16BT 패러렐 이미지 36개 추가
- VERSION과 API 버전을 v4.0.27로 통일
- Git 원격 주소와 배포 문서의 저장소 주소를 새 경로로 갱신
### 검증
- 카드 데이터 모듈 로딩 및 번역 JSON 파싱 확인
- UA57 이미지 95개 존재 확인, 패러렐 이미지 33개 미확보
- UA31 참조 이미지 중 기존 `UAPB_MMM-1-AP01.png` 1개 누락 확인
- CSS 변경이 없어 CSS 빌드 생략, 운영 배포·브라우저 검증 미수행
## 2026-09-22 / v4.0.26 — 魔法少女まどか☆マギカ EX16BT 추가
### 수행 작업
- `ua31` 魔法少女まどか☆マギカ 카드 데이터에 EX16BT/MMM-2 카드와 관련 UAPR·UAPB 카드를 추가
- EX16BT/MMM-2 일반 카드 이미지와 관련 프로모 이미지를 `images/ua31`에 추가
- 패러렐 판본은 데이터 참조를 먼저 반영하고, 실제 이미지는 후속 추가 대상으로 유지
### 검증
- `datas/ua31.js` 문법 검증 통과
- EX16BT 일반 이미지와 관련 프로모 이미지 파일 존재 확인
## 2026-09-15 / v4.0.25 — UA56 이미지 보정
### 수행 작업
- `UA56BT/TTG-1-015` 카드 이미지를 실제 누락 이미지로 교체
### 검증
- UA56 카드 데이터 131건의 참조 이미지 파일 존재 확인 예정
## 2026-09-15 / v4.0.24 — UA56 카드 시리즈 추가·BLC 이미지 보강
### 수행 작업
- `ua56` 천원돌파 그렌라간 카드 데이터 131건 추가
- UA56 카드 이미지 131개 추가
- `ua08` BLEACH BLC-4 및 관련 누락 카드 데이터·이미지 보강
- 한국어·일본어·영어 시리즈명 번역 추가
### 검증
- 번역 JSON 3개 파싱 통과 예정
- 카드 데이터 참조 이미지 파일 존재 확인 예정
## 2026-08-12 / v4.0.23 — 운영 지표 API 추가
### 수행 작업
- 외부 대시보드용 `GET /api/stats`, `GET /api/v1/stats` 추가
- 회원·덱 집계와 카드 시리즈·고유 카드 번호·패러렐 포함 카드 수 집계 추가
- `.env`의 `STATS_API_TOKEN` 설정 시 Bearer 또는 `X-Stats-Token` 인증 적용
- 외부 대시보드 위젯 문서와 API 명세 갱신
### 검증
- 통계 API 라우트 테스트 추가
- API 테스트 전체 실행 예정
## 2026-08-09 / v4.0.22 — UA55 카드 시리즈 추가
### 수행 작업
- `ua55` 아이돌마스터 신데렐라 걸즈 카드 데이터 216건 추가
- UA55 카드 이미지 216개 추가
- 한국어·일본어·영어 시리즈명 번역 추가
### 검증
- 번역 JSON 3개 파싱 통과
- 카드 데이터 216건과 참조 이미지 216개의 파일 존재·대소문자 일치 확인
## 2026-07-03 / v4.0.21 — 정합성·보안·인덱스 개선
### 수행 작업
- `/api/v1/health` 응답과 시작 로그 버전을 `package.json` 기준으로 동적화(기존 `4.0.16` 고정값 제거)
- `express-rate-limit` 도입: 로그인 10회/10분, 계정·이메일 쓰기(회원가입·인증메일·이메일검증·비밀번호 찾기/재설정) 30회/10분(IP 기준)으로 제한
- API에 `trust proxy = 1` 설정으로 nginx 뒤에서 실제 클라이언트 IP 기준 제한 적용
- nginx 보안 헤더 추가: HTML은 `X-Content-Type-Options`/`X-Frame-Options`/`Referrer-Policy`, 정적 자산(css·js·이미지)은 `X-Content-Type-Options: nosniff`
- 공개 덱 목록 조회용 복합 인덱스 `idx_decks_public_list(share_type, is_public, updated_at)` 추가
### 검증
- 서버 모듈 `node --check` 및 auth 라우트 import 검증 통과
- nginx 설정은 표준 디렉티브만 사용(배포 시 `nginx -t` 권장)
## 2026-07-03 / v4.0.20 — 전송 최적화(gzip·lazy-load·캐시)
### 수행 작업
- nginx에 텍스트 자산 gzip 압축 추가(css/js/json/svg 등, `gzip_min_length 1024`, `comp_level 6`) — output.css·카드 데이터·HTML 전송량 약 70~80% 절감
- `cardList.html` 카드 그리드 이미지에 `loading="lazy" decoding="async"` 추가 — 시리즈 진입 시 전체(~90장) 즉시 다운로드 방지
- 정적 이미지 캐시 기간 `expires 7d → 30d`로 연장(내용 고정, immutable 유지)
- 미사용 `style/deck-history.css`(10.8KB) 삭제 (현재 어떤 화면도 참조하지 않음)
### 검증
- nginx 설정은 문법상 표준 디렉티브만 사용(배포 시 `nginx -t` 권장)
- `deck-history.css` 참조가 HTML/CSS/Dockerfile에 없음을 확인 후 삭제
## 2026-07-02 / v4.0.19 — 덱 목록 무한 스크롤·WebP 썸네일
### 수행 작업
- 공용 무한 스크롤 페이저 모듈 `script/deck-list-pager.js` 추가 (IntersectionObserver 기반, 청크 24개, 하단 근접 시 이어붙임, 미지원 시 전체 렌더 폴백)
- `preset.html`, `deckHistory.html` 덱 목록을 무한 스크롤로 전환해 대량 덱에서도 초기 DOM 렌더 부담 완화
- 즐겨찾기 토글 시 전체 리렌더 대신 해당 카드만 in-place 갱신해 스크롤 위치 유지(즐겨찾기 필터 모드에서는 리렌더 유지)
- 저장 시 클라이언트가 원본(1200px PNG)과 함께 목록용 축소 썸네일(420px WebP, 품질 0.82)을 생성·전송 (`result.html`)
- API가 썸네일을 `<shareCode>.thumb.webp`로 저장하고 `GET /decks/:shareCode/thumbnail` 및 응답 `thumbnail_url`/`thumbnailUrl` 제공
- 목록 화면(내 덱·공개 덱·관리자)은 썸네일 우선 표시, 길게 눌러 확대할 때만 원본 사용
- 덱 삭제·미참조 정리(orphan)가 원본 PNG와 썸네일 WebP를 함께 처리하도록 확장
### 검증
- 서버 모듈 `node --check` 문법 검증 통과 (previewImage.js, decks.js, admin.js)
- 프론트 lint 확인(신규/수정 파일 오류 없음, 기존 Tailwind 경고만 잔존)
## 2026-06-25 / v4.0.18 — 누락 이미지 폴백·공유 덱 매핑 보정
### 수행 작업
- 덱 저장 카드 payload를 `imgSrc` 필수로 확장하고 API 검증에서 `imgSrc` 누락 요청을 차단
- 덱 복원은 `imgSrc` 기준으로 정확 매핑하고, 기존 구데이터 호환을 위해서만 `number`를 보조 fallback으로 유지
- `cardList.html`, `result.html` 카드 렌더링에서 이미지 로드 실패 시 공통 폴백(`/images/uapr/comingsoon.png`)을 사용
- 카드 목록 확대 미리보기(오버레이)도 동일 폴백을 적용해 이미지 누락 시 깨짐 대신 뒷면 노출
- 관리자 덱 카드에 `불러오기` 버튼과 길게 눌러 썸네일 확대 미리보기를 복구하고, 체크박스 다중 선택 기능과 충돌하지 않도록 이벤트를 분리
- 관리자 회원 수정에서 별도 탈퇴 버튼을 제거하고 `역할 변경하기` 선택지에 `회원 탈퇴 처리`를 통합, 저장 시 2단계 확인 후 탈퇴 실행으로 변경
## 2026-06-25 / v4.0.16 — 회원 탈퇴·관리자 덱 일괄 삭제
### 수행 작업
- 프로필 최하단에 10px 연회색 일반 텍스트 형태의 `회원 탈퇴` 진입점 추가
- 탈퇴 모달에서 `DELETE` 확인 입력과 `YES`·`NO` 버튼 제공
- 본인 탈퇴 및 관리자 회원 탈퇴 API 추가, 현재 로그인한 관리자 본인 삭제 차단
- 탈퇴 시 계정·인증 토큰·메일 기록·즐겨찾기·아바타 삭제
- 탈퇴 회원의 저장 덱과 썸네일은 유지하고 작성자 연결만 제거해 익명 처리
- 관리자 덱 관리에 복수 체크·현재 목록 전체 선택·최대 100개 일괄 삭제 추가
- 계정 탈퇴 후 동일 사용자명 재가입과 익명 덱 분리, 본인·관리자 탈퇴 API 회귀 테스트 보강
## 2026-06-25 / v4.0.15 — 미인증 로그인 복구·인증 화면 다국어
### 수행 작업
- 미인증 계정 로그인 시 같은 화면에서 인증 메일 재발송 기능 표시
- 최초 발송 포함 월 3회 제한과 초과 시 `zenn@sori.studio` 관리자 문의 안내 추가
- 관리자 회원 화면에 미인증 상태와 `이메일 인증 승인` 기능 추가
- API 오류의 상태·코드를 프론트까지 전달해 미인증·월 한도 오류를 구분
- 인증 완료 후 로그인 화면에 선택 언어 기준 완료 메시지 표시, 기본 언어는 한국어로 보정
- `비밀번호를 잊으셨나요?`, 인증·비밀번호 찾기·재설정 화면을 한국어·일본어·영어 번역에 연결
- 계정 삭제 후 동일 사용자명 재가입 시 기존 덱·인증 정보가 연결되지 않는 DB 회귀 테스트 추가
## 2026-06-25 / v4.0.14 — 계정별 월간 메일 한도
### 수행 작업
- 가입 인증·인증 재전송·비밀번호 재설정 메일을 계정별 월 3회로 통합 제한
- 한국 시간 기준 월별 발송 기록을 `email_send_logs`에 저장
- 동시 요청은 발송 전 횟수를 예약해 월 한도 우회 방지
- Resend 발송 실패 시 예약을 취소해 무료 횟수가 잘못 차감되지 않도록 처리
- 한도 초과 시 `zenn@sori.studio` 관리자 문의 안내 반환
## 2026-06-25 / v4.0.13 — 인증 캐시·중복 제출 방지
### 수행 작업
- 이메일 인증 화면이 캐시된 구 `api.js`를 불러와 `verifyEmail`을 찾지 못하던 문제 수정
- 인증 메일 링크·인증 화면에 `v=4.0.13` 캐시 무효화와 직접 API 호출 폴백 적용
- 회원가입·로그인·인증 메일·비밀번호 찾기·재설정 요청 중 버튼 잠금과 로딩 스피너 표시
- 인증 메일과 비밀번호 재설정 메일 전송 후 60초 재요청 대기 표시
## 2026-06-25 / v4.0.12 — 이메일 인증·비밀번호 재설정
### 수행 작업
- 신규 회원가입 시 Resend 이메일 인증 링크 발송, 인증 완료 전 로그인 차단
- 인증 메일 재전송과 24시간·1회용 인증 토큰 적용
- 비밀번호 찾기·30분 만료 재설정 링크·사용자 직접 비밀번호 변경 화면 추가
- 이메일 형식 서버 검증과 사용자명 대소문자 무시 중복 검사 적용
- 기존 회원은 배포 시 이메일 인증 완료 상태로 마이그레이션
- Resend 환경 변수와 운영 배포·확인 절차 문서화
## 2026-06-24 / v4.0.11 — 로그인 유지·마지막 접속 갱신 개선
### 수행 작업
- 로그인 화면에 `로그인 유지` 선택 항목 추가
- 선택 시 인증 정보를 `localStorage`, 미선택 시 `sessionStorage`에 저장하도록 분리
- 기존 로그인 유지 사용자의 로컬 인증 정보 호환 유지
- 인증된 사용자의 `/auth/me` 세션 확인 성공 시 `last_login_at` 갱신
- 로그인 유지 문구를 한국어·일본어·영어 번역에 반영
## 2026-06-23 / v4.0.10 — 관리자 권한 변경 안전장치·접속 시간 표시
### 수행 작업
- `admin.html` 회원 수정 모달에서 역할 선택 UI를 기본 숨김으로 전환하고, `역할 변경하기` 버튼을 눌렀을 때만 노출
- 회원 카드에 마지막 접속 상대시간(`분/시간/일/달 전`) 표시 추가
- `users` 스키마에 `last_login_at` 컬럼 추가(마이그레이션 포함), 로그인 성공 시 마지막 접속 시각 기록
- `GET /api/v1/admin/users`, `GET /api/v1/admin/users/:id` 응답에 `lastLoginAt` 포함
- `login.html`에 비밀번호 분실 시 `zenn@sori.studio` 문의 안내 문구 추가
## 2026-06-19 / v4.0.9 — 관리자 회원 목록 2열·덱 이용 통계
### 수행 작업
- `admin.html` 회원 카드: `sm:grid-cols-2` 2열 그리드, 카드 패딩·아바타 크기 축소
- 회원별 저장 덱 수 `공개/전체` 형식 표시 (관리자 전용)
- `GET /api/v1/admin/users`: `deckPublic`, `deckTotal` 필드 추가 (`share_type='user'` 기준)
- `GET /api/v1/admin/users/:id`: `deckPublic`, `deckTotal` 분리 반환
- `admin.html` `output.css?v=4.0.9`, `npm run build:css` 재실행
## 2026-06-23 / v4.0.8 — nginx 정적 캐시·deck-favorites 배포 수정
### 수행 작업
- 운영 HTML이 v4.0.6·JS가 CDN `immutable` 구버전으로 남아 `init` 오류 지속
- `docker-compose.prod.yml`: `nginx/default.conf` 볼륨 마운트 추가
- nginx: HTML·`deck-favorites.js`·`api.js` `no-cache`, JS `immutable` 제거
- `script/deck-favorites-shim.js`: 구버전 JS에 `init`/`forget` 폴리해
- `docs/deploy.md`: 호스트 vs 컨테이너 vs Cloudflare 3단계 검증 명령 추가
## 2026-06-23 / v4.0.7 — 덱 목록 JS 캐시·init 오류 수정
### 수행 작업
- 운영 `deck-favorites.js` 구버전( `init` 없음) + CDN JS 캐시로 `UaDeckFavorites.init is not a function` 발생 → 덱 로드 중단
- `deckHistory.html`·`preset.html`: 스크립트에 `?v=4.0.7` 캐시 무효화, `init` 없을 때도 `loadDecks` 실행되도록 방어 코드
## 2026-06-23 / v4.0.6 — CSS 캐시·배포 반영 수정
### 수행 작업
- 운영 확인: `login.html`은 갱신됐으나 `output.css`가 구버전(44KB) + CDN 7일 immutable 캐시로 Tailwind 클래스 미적용
- 로그인·회원가입·내 덱·공개 덱·관리자: `output.css?v=4.0.6` 쿼리로 캐시 무효화
- `nginx/default.conf`: CSS는 `must-revalidate` 1시간, JS·이미지는 기존 7일 유지
- NAS 배포 시 `git pull` 후 `wc -c style/output.css`로 약 55KB 확인 (`docs/deploy.md`)
## 2026-06-23 / v4.0.5 — 로그인·덱·관리자 Tailwind 레이아웃 통합
### 수행 작업
- `style/components.css` 신설: 앱 셸·인증 헤더·덱 카드 스타일을 `@layer components`로 빌드에 포함
- `style/input.css`: `brand.css`·`components.css` import, `@source`로 HTML·JS 스캔
- 로그인·회원가입·관리자: `app-page`/`app-nav`/`app-shell` + Tailwind 유틸리티로 레이아웃 정리
- 내 덱·공개 덱: `output.css` 단일 로드 (AdSense 레일 유지)
- `cardList`·`result`·`index`·`profile` 등 기존 페이지는 변경 없음
## 2026-06-23 / v4.0.4 — Tailwind 빌드·로그인/관리자 레이아웃 수정
### 수행 작업
- `style/input.css`: `@source`로 HTML·JS만 스캔하도록 지정 (`images/`·`datas/` 제외) — arbitrary 클래스가 `output.css`에 누락되던 문제 해결
- `focus:ring-3`(미지원) → `focus:ring-2`로 수정
- `npm run build:css` 재실행
- `docs/posts/` gitignore 처리 및 프로젝트 문서에서 posts 참조 제거
## 2026-06-23 / v4.0.4 — 비회원 덱 저장 제한
### 수행 작업
- 비회원은 덱 구성과 PNG 이미지 다운로드만 이용하도록 정책 변경
- `POST /api/v1/decks`에 필수 인증 적용
- 결과 화면의 비회원 저장 버튼을 `로그인 후 덱 저장`으로 안내
- 기존 비회원 공유 덱은 만료일까지 조회 호환 유지
- 서비스 소개 글과 기능 명세·변경사항 갱신
## 2026-06-23 / v4.0.3 — 계정 즐겨찾기 동기화
### 수행 작업
- 로그인 사용자의 즐겨찾기를 `deck_favorites` DB 테이블에 계정별 저장
- 다른 브라우저와 기기에서도 같은 계정의 즐겨찾기 유지
- 기존 브라우저 즐겨찾기는 로그인 시 접근 가능한 덱만 계정으로 자동 이전
- 덱 삭제 시 외래키로 관련 즐겨찾기 자동 삭제
- 만료되거나 타인이 비공개로 전환한 덱은 즐겨찾기 조회 시 자동 정리
- 비로그인 사용자는 기존처럼 브라우저 `localStorage` 즐겨찾기 사용
- 개인 NAS·자체 Git LFS 운영 구조에 불필요한 CDN 분리 TODO 제거
- `todo.md`에 화면별 Tailwind 전환 체크리스트 추가
- 관리자 레이아웃·회원 관리·모달·정리 도구를 Tailwind 유틸리티로 전환
- 관리자 탭·모달 상태도 JavaScript에서 Tailwind 클래스를 전환하도록 변경하고 `style/admin.css` 제거
- 로그인·회원가입 화면을 Tailwind 유틸리티로 전환하고 `style/auth-pages.css` 제거
- Google Fonts 외부 호출을 제거하고 Pretendard 우선 시스템 폰트 스택 적용
- `style/output.css` 재빌드
- 메인 페이지 검색 제목·설명을 UNIARE 기준으로 변경하고 canonical·Open Graph·Twitter·구조화 데이터 추가
- 검색 엔진이 빈 제목이나 `Failed to fetch` 오류를 수집하지 않도록 정적 기본 문구와 사용자용 오류 안내 적용
## 2026-06-23 / v4.0.2 — 관리자 덱 관리·썸네일 정리 개선
### 수행 작업
- 관리자 화면 본문에 반응형 좌우 여백을 적용해 좁은 화면에서 콘텐츠가 벽에 붙는 문제 수정
- 관리자 덱 목록을 내 덱 화면과 같은 시리즈·공개 상태·수정일 카드 구조로 변경
- 조회 수와 `/d/공유코드` 표시 제거, 삭제 기능을 더보기 메뉴로 이동
- 일반 사용자와 관리자 덱 삭제 API에서 연결된 미리보기 PNG도 함께 삭제
- 관리자가 미참조 썸네일의 파일명·용량·수정일을 확인하고 일괄 삭제하는 기능 추가
## 2026-06-23 / v4.0.1 — 프로젝트 문서 체계 정비
### 수행 작업
- 실제 코드와 Git 이력을 기준으로 `spec.md`, `todo.md`, `history.md`, `map.md`, `convention.md`를 현재 상태에 맞게 재작성
- 과거 주요 구현 결정을 `history.md` 형식에 맞춰 날짜·버전·결정 이유·적용 내용으로 복원
- 누락된 `VERSION`, `docs/widget.md`, `docs/changelog.md` 추가
- `deploy.md`를 최초 설치·실행·업데이트·백업·롤백 순서의 운영 가이드로 전면 재작성
- `deploy.md`에서 로컬 개발과 NAS 운영을 분리하고 이미지·`datas/`·API 변경별 반영 명령을 구분
- `AGENTS.md` 재검수 결과를 반영해 SQLite WAL 안전 백업·복구 절차와 Compose 고정 이름 제약을 문서화
- Custom API YAML을 공식 문서 기준으로 재확인하고 참고 URL 추가
- `.cursorrules`의 잘못된 `.AGENTS.md` 참조를 `AGENTS.md`로 수정하고 배포 문서의 개인 로컬 절대 경로를 제거
- `deploy.md`의 중복 설명을 제거하고 초심자가 상황별 절차를 바로 선택할 수 있도록 간소화
- `deploy.md`의 Markdown 표를 제거하고 불필요한 줄바꿈을 줄여 명령 중심으로 재정리
- `deploy.md`의 한 줄 명령은 인라인 코드로 변경하고 여러 명령을 연속 실행하는 경우만 코드 블록 유지
- 완료 항목이 남아 있던 `todo.md`를 미완료 작업만 유지하도록 정리
- 현재 단계에서는 기존 CSS 구조를 유지하고 Tailwind 일괄 전환을 제외한다고 명시
## 2026-06-22 / v4.0.0 — 헤더 로고 크기 통일
### 수행 작업
- `style/brand.css` 신설: `--brand-logo-height: 2rem`(32px), `.app-brand-logo` 단일 정의
- `app-shell.css`, `auth-pages.css`, `admin.css`에서 중복 로고 스타일 제거 → `@import brand.css`
- `index.html`: Tailwind `h-8` 제거 → `app-brand-logo` + `brand.css` 로드
## 2026-06-22 / v4.0.0 — 덱 카드 조회 수 제거
### 수행 작업
- `deckHistory.html`, `preset.html`: 카드 메타에서 조회 수 표시 제거 (저장일·작성자만 유지)
## 2026-06-22 / v4.0.0 — 제품명 UNIARE·로고 이미지
### 수행 작업
- 표시 제품명 `UADECK` → **UNIARE** (페이지 title, i18n, 관리자, 연동 문서)
- 상단 헤더 텍스트 로고 → `images/assets/uniare-h48.png` 이미지 로고
- 이미지 다운로드 파일명 접두사 `uadeck_` → `uniare_`
- 내부 호환 유지: `UaDeckApi`, `uadeck_token`, `uadeck.db`, `UADECK_API_BASE` 등
## 2026-06-22 / v4.0.0 — Tailwind CSS 재빌드
### 수행 작업
- `package.json`: `npm run build:css` 스크립트 추가
- `style/output.css` 재생성 — `sm:px-6` 등 HTML에 추가됐으나 빌드에 없던 클래스 반영
- `cardList.html`, `result.html`: `px-4 sm:px-6` 유지 (클래스 우회 제거)
## 2026-06-22 / v4.0.0 — 레이아웃·덱 이름 변경
### 수행 작업
- 헤더 `v4.0.0` 표시 제거 (로그인 페이지 하단 푸터에만 작게 표시)
- `deckHistory.html`: 더보기 메뉴에 **이름 변경** 추가 (`PUT /decks/:code`)
- `cardList.html`, `result.html`: 콘텐츠·헤더 최대 너비 `1400px` → **1280px** (`max-w-7xl`) 통일
- `profile.css`: 프로필 본문 `max-width: 42rem` 제거 → 내 덱·공개 덱과 동일한 `app-main` 너비
## 2026-06-22 / v4.0.0 — Docker 서비스명 `uniare-*` 통일
### 수행 작업
- `docker-compose.prod.yml`: 서비스/컨테이너/이미지/볼륨 이름을 `uadeck-*`에서 `uniare-*`로 변경
- `docker-compose.yml`: API 서비스/컨테이너/볼륨 이름을 `uniare-*`로 변경
- `nginx/default.conf`: 내부 API 프록시 대상 `uadeck-api` → `uniare-api` 반영
- `nginx/uadeck.conf`: API 프록시 대상 컨테이너 이름을 `uniare-api`로 갱신
- `docs/deploy.md`: 운영 명령 및 컨테이너 확인 예시 이름을 `uniare-*` 기준으로 갱신
### 메모
- API DB 파일명(`uadeck.db`)과 API 경로(`/api/v1/*`)는 호환성을 위해 유지했다.
## 2026-06-19 / v4.0.0 — 덱 썸네일 미리보기·저장 크기 통일
### 수행 작업
- `deckHistory.html`: `deck-preview-hold.js` 연동 — 내 덱 썸네일도 클릭·길게 눌러 확대
- `preset.html`: 썸네일 위「클릭·길게 눌러…」안내 문구 제거 (홀드 기능 유지)
- `result.html`: 저장용 미리보기를 다운로드와 동일한 **1200px** 기준으로 정규화 (`normalizePreviewForSave`)
- 저장 시 HQ 옵션 무시 (`highQuality: false`) 후 너비 1200px로 스케일
- 기존 960px 축소만 하던 `compressPreviewForSave` 제거 → 크기 제각각이던 원인 해소
- `style/deck-history.css`: 미사용 `.deck-card-preview-hint` 제거
### 참고
- 이미 저장된 덱 썸네일은 예전 크기 그대로이며, Preview에서 **다시 저장**하면 1200px로 갱신됨
## 2026-06-19 / v4.0.0 — 덱 저장 413 수정
### 원인
- `localhost:8080` 요청은 Nginx(`client_max_body_size 2m`)를 거침
- 덱 저장 시 미리보기 PNG(base64)가 JSON에 포함되어 2MB 초과 → **413 Request Entity Too Large**
### 수행 작업
- `nginx/default.conf`: `client_max_body_size` 2m → **25m** (API location 포함)
- `api/src/index.js`: JSON limit 20mb, 413 전용 오류 메시지
- `script/api.js`: 413 사용자 안내 문구
- `result.html`: 저장용 미리보기 최대 너비 960px 리사이즈
### 적용
```bash
npm stop && npm start
```
## 2026-06-19 / v4.0.0 — 공개 덱 미리보기 수정
### 수행 작업
- `deck-preview-hold.js`: mouseleave 즉시 닫힘 버그 수정, 길게 누르는 동안만 확대 (짧은 클릭 고정 제거)
- ~~안내 문구:「클릭·길게 눌러 크게 보기」~~ → 이후 제거됨
## 2026-06-19 / v4.0.0 — 프로필 덱 저장 설정 UI
### 수행 작업
- 덱 저장 설정: 설명 문단 제거 → `?` 툴팁, 설정 패널·토글 ON/OFF 표시·즉시 저장 안내 메시지
- 토글 클릭 시 API/localStorage 동기화는 기존 `deck-prefs.js` 유지
## 2026-06-19 / v4.0.0 — 메인 프로필 i18n·페이지 도움말
### 수행 작업
- `index.html`: `page-i18n.js` 로드, 언어 전환 시 `UaPageI18n` + `UaDeckAuth.refresh()`로 프로필 드롭다운 재번역
- `script/page-help.js`: 제목 옆 `?` 버튼 클릭 시 설명 툴팁
- `deckHistory.html`, `preset.html`, `profile.html`: 상단 설명 `<p>` 제거 → `?` 도움말 버튼
- `style/app-shell.css`: `.page-title-row`, `.page-help-btn`, `.page-help-tooltip`
## 2026-06-19 / v4.0.0 — 덱 즐겨찾기·공개 덱 미리보기
### 수행 작업
- `script/deck-favorites.js`: share_code 기준 즐겨찾기 (localStorage)
- `script/deck-preview-hold.js`: 썸네일 길게 누르기 확대 미리보기
- `deckHistory.html`: 카드 하단 즐겨찾기 버튼, 툴바「즐겨찾기」필터
- `preset.html`: 카드 클릭 이동 제거 → 홀드 미리보기 + 하단「즐겨찾기」「불러오기」버튼
- `style/deck-history.css`: 즐겨찾기·홀드 오버레이 스타일
- i18n: `deckFavorite`, `deckFavoriteFilter`, `deckHoldPreviewHint`
### 메모
- 즐겨찾기는 브라우저 localStorage에 저장 (기기·브라우저별). 추후 계정 동기화 API 확장 가능.
## 2026-06-19 / v4.0.0 — AdSense·i18n 보완
### 수행 작업
- Google AdSense 우측 슬롯(`4260332296`) 삽입: `deckHistory.html`, `preset.html`, `profile.html` `#ad-sidebar`
- `script/ads.js`: `ins.adsbygoogle` 초기화 헬퍼
- `script/page-i18n.js`: `data-i18n` / `data-i18n-html` / `data-i18n-placeholder` + `UaPageI18n.t()` 헬퍼
- `script/auth-header.js`: 드롭다운 메뉴 3개국어(ko/en/ja)
- `login.html`, `signup.html`, `profile.html`, `deckHistory.html`, `preset.html` 정적 문구 i18n 연결
- `cardList.html`: `← 홈` 버튼 `homeNav` 키 적용
- `result.html`: 저장 모달·로딩 확인·홈 버튼 기존 `applyTranslationsToUI` 유지, `page-i18n`으로 헤더 메뉴 번역
- `deckHistory.html` / `preset.html`: 목록·버튼·확인 대화상자 동적 문구 i18n
- `i18n/translations.{ko,en,ja}.json`: auth·덱 관리·프로필·공개 덱 관련 키 추가
### 확인
- `?lang=en` 또는 `?lang=ja` 로 각 페이지 문구 전환 확인
- AdSense는 로컬/비승인 도메인에서는 빈 슬롯으로 보일 수 있음
## 2026-06-19 / v4.0.0
### 수행 작업
- v4.0.0 회원·덱 API·공유 시스템 1차 구현
- `api/` Express + SQLite 백엔드 (인증, 덱 CRUD, 관리자 API)
- `docker-compose.yml`, `.env.example`, `nginx/uadeck.conf` 추가
- 프론트: `script/api.js`, `script/auth-header.js`, `style/auth-header.css`
- 신규 페이지: `login.html`, `signup.html`, `deckHistory.html`, `preset.html`, `admin.html`
- `index.html` v4.0.0 + 프로필 헤더
- `cardList.html`: `?cards=` 제거, `?d=` API 로드, 저장·공유 버튼
- `result.html`: localStorage 기반, 프로필 헤더
- `docs/spec.md` §9 API·DB 명세 반영
### 배포 방법
1. `.env.example`을 `.env`로 복사 후 `JWT_SECRET`, `ADMIN_EMAIL`, `ADMIN_PASSWORD` 설정
2. `docker compose up -d --build`
3. 리버스 프록시에 `nginx/uadeck.conf` 규칙 적용 (`/api/`, `/d/`)
### 메모
- 비회원도 저장·공유 가능 (30일 만료). 회원은 영구 저장.
- 외부 연동: `GET /api/v1/decks/:shareCode`, 클라이언트 `integrations/uadeck-deck-client.js`
## 2026-06-19 / v4.0.0 덱 저장 UX
### 수행 작업
- `cardList.html` 저장·공유 버튼 제거
- `result.html` 하단 Back 제거 →「내 덱에 저장」「공유」버튼 추가
- 저장·공유 시 Preview 이미지 PNG 함께 API 저장 (`preview_image`)
- 덱 이름: 입력값 없으면 `시리즈명 YYYY-MM-DD`
- `deckHistory.html` 미리보기 썸네일 표시
- 로그아웃 시 메인(`/`)으로 이동
- `seedAdmin`: `ADMIN_EMAIL`로 먼저 가입한 경우 역할을 `admin`으로 승격 (기존에는 INSERT 실패로 관리자 미생성)
- `auth-header.js`: 프로필 메뉴 열 때 `/auth/me`로 role 재동기화 (관리자 메뉴 미표시 수정)
- 관리자 API: JWT role 대신 DB role 확인 (`createRequireAdmin`)
- `npm start` / `npm stop` / `npm run logs` 로컬 실행 명령 정리 (`package.json`)
- 관리자 덱 관리 썸네일, 회원 모달 개편 (아바타·비밀번호 분리 모달)
- 본인 계정 역할/비활성 변경 서버·UI 차단, 표시 이름 필드 제거 (사용자명 사용)
## 2026-06-19 / v4.0.0 — 공개 덱·관리자 UI
### 수행 작업
- 메타 덱: 관리자 프리셋 등록 폐기 → 사용자 `is_public` 공개 덱이 `/preset.html`(공개 덱)에 노출
- 내 덱 저장 기본 비공개, 공유 시 공개, 내 덱 관리에서 공개/비공개 전환
- 덱 이름 기본값: `YYYYMMDD_HHMMSS` (시리즈명 제외)
- `admin.html` 레이아웃 개편 (`style/admin.css`), 프리셋 등록 탭 제거
- `preset.html` 카드 그리드 + 필터 UI
## 2026-06-19 / v4.0.0 — 프로필·아바타
### 수행 작업
- **썸네일(프로필 사진) 미적용 원인**: JPEG 등을 `.png`로 그대로 저장해 브라우저 표시 실패 → 업로드 전 `canvas`로 PNG 변환 (`script/image-utils.js`)
- `profile.html` 신규: 일반 사용자가 이메일·사용자명·아바타·비밀번호 변경 (`PUT /auth/me`, `POST /auth/me/password`)
- 헤더 드롭다운에「내 프로필」추가 (`script/auth-header.js`)
- 아바타 URL에 `updatedAt` 쿼리로 캐시 무효화 (저장 후 즉시 반영)
- `admin.html` 아바타 업로드도 동일 PNG 변환 적용
- `script/api.js`: `updateProfile`, `changePassword` 추가
- `docs/spec.md` 인증 API 엔드포인트 보강
### 확인 방법
1. `npm stop && npm start` 로 API 재시작 (auth 라우트 변경 반영)
2. http://localhost:8080/profile.html 에서 사진 업로드 →「프로필 저장」
3. 헤더 썸네일 클릭 →「내 프로필」메뉴 확인
### 후속
- 헤더 프로필 버튼: 로그인 시 아바타 옆 사용자명 표시 (`auth-header.js`, `auth-header.css`)
## 2026-06-19 / v4.0.0 — 덱 저장 UX·네비게이션
### 수행 작업
- `deckHistory.html`: `/d/코드` 경로 표시 제거 (링크 복사 버튼 유지)
- `result.html` 하단 버튼: `홈으로` / `이미지로 다운로드` / `내 덱으로 저장`
- 저장 시「모두에게 공개할까요?」모달 +「다음부터 물어보지 않기」토글
- `script/deck-prefs.js`: 공개 기본값·프롬프트 스킵 (localStorage + API 동기화)
- `users` 테이블: `default_deck_public`, `skip_deck_public_prompt` 컬럼 추가
- `profile.html`: 덱 저장 설정 (기본 공개, 물어보기 on/off)
- 뒤로가기 루프 수정: `result.html` 편집 복귀 시 `history.back()`, `cardList` ← 홈 버튼
### 확인
- API 변경 반영: `npm stop && npm start` (또는 `docker compose up -d --build`)
## 2026-06-19 / v4.0.0 — 레이아웃 통일·광고 공간
### 수행 작업
- `style/app-shell.css` 추가: 헤더·본문 `80rem`(1280px, index `max-w-7xl`과 동일)
- `deckHistory.html`, `preset.html`, `profile.html` 공통 셸 적용 (페이지 이동 시 헤더 너비 점프 제거)
- 데스크톱: 본문 좌측 + 우측 300px 광고 레일(`app-ad-rail`), 모바일: 상단 리더보드 슬롯
- 프로필 폼은 콘텐츠 영역 내 `max-width: 42rem` 유지
- `auth-pages.css`, `admin.css` 너비도 80rem으로 통일
### 후속 UI
- `result.html` 저장 모달 토글: Tailwind `translate-x-6` 미빌드 → 전용 `.save-deck-switch` CSS
- `result.html` 하단 버튼 비율: 홈 0.5 · 다운로드 0.5 · 내 덱 저장 2
- `result.html` 덱 저장: 브라우저 alert 제거 → 로딩 모달 완료 메시지 후 홈 이동
- `signup.html`: 비밀번호 확인 필드, 가입 후 홈(`/`) 이동
- `cardList.html`: 동일 카드 번호(패러랠 포함) 수량 공유 시 +/- 버튼 UI 동기화
## 2026-06-19 / v4.0.0 — 덱 썸네일 수정
### 수행 작업
- Preview 캡처 시 카드 이미지 로드 대기 + `cacheBust` 추가 (`result.html`)
- 캡처 실패해도 덱 저장은 진행, 안내 메시지 표시
- `deckHistory.html`: `UaDeckApi.resolveMediaUrl()`로 미리보기 URL 보정 (Live Server 등)
- 이미지 로드 실패 시 플레이스홀더 표시
- Docker 미리보기 저장 경로를 `./api/data/previews` 호스트 바인드 마운트로 변경
- API `getPreviewUrl`: DB `preview_image` 컬럼도 참고
## 2026-06-19 / v4.0.0 UI — 내 덱 관리
### 수행 작업
- `deckHistory.html` 카드 그리드 레이아웃으로 개편 (미리보기 이미지 상단 배치)
- `style/deck-history.css` 추가: 상단 여백, 툴바, 카드 그리드 전용 스타일
- 시리즈별 필터 드롭다운 + 덱 이름·시리즈 검색 입력 추가
- Tailwind 미빌드 클래스 의존 제거
## 2026-06-19 / v4.0.0 UI — result 하단 버튼
### 수행 작업
- `result.html` 하단「내 덱에 저장」「공유」버튼이 `style/output.css`에 없는 Tailwind 클래스(`bg-slate-700`, `bg-emerald-600`)로 인해 보이지 않던 문제 수정
- 페이지 내 `<style>`에 `.result-footer-*`, `.result-btn-*` 전용 스타일 추가 (인증 페이지와 동일한 패턴)
## 2026-06-19 / v4.0.0 UI — 인증 페이지
### 수행 작업
- `style/auth-pages.css` 추가: 폼 최대 너비 28rem, 상단 여백, index와 동일한 그라데이션·폰트
- `login.html`, `signup.html` 레이아웃 개선 (Tailwind 미빌드 클래스 의존 제거)
## 2026-06-19 / v4.0.0 배포·연동 보강
### 수행 작업
- `docker-compose.prod.yml`: Nginx + API 풀스택 (정적 파일 볼륨 마운트, 재빌드 불필요)
- `nginx/default.conf`, `docs/deploy.md` NAS 배포 가이드
- `integrations/uadeck-deck-client.js` 옆 프로젝트용 클라이언트
- `docs/api-integration.md` API 연동 문서
- `admin.html` 프리셋 등록 탭 추가
## 2026-06-19 / v4.0.0
### 수행 작업
- v4 회원·덱 API·공유 방식 설계를 확정했다.
- URL 쿼리(`?cards=`) 기반 공유는 폐기하고, 공유 코드 + `GET /api/v1/decks/:shareCode` API로 전환하기로 했다.
- 개인 덱은 저장마다 고유 `share_code`, 메타 덱·프리셋은 내용 해시 기반 고정 코드를 사용한다.
- DB 스키마 초안(`users`, `decks`)과 API 엔드포인트 목록을 `docs/spec.md` §9에 반영했다.
- 의사결정 내용을 `docs/history.md`에 기록했다.
### 메모
- 구현은 이 설계를 기준으로 진행한다. 실제 코드·Docker·화면 작업은 다음 단계다.
- 옆 프로젝트는 API 계약만 맞추면 되며, 레거시 쿼리 호환은 필요 없다.
## 2026-04-19 / v3.1.0
### 수행 작업
- `datas/ua51.js`를 추가해 `ua51` 시리즈 데이터를 등록했다.
- `images/ua51/`에 `나 혼자만 레벨업` 카드 이미지 자산을 반영했다.
- `images/ua49/`에 누락되어 있던 `마도정병의 슬레이브` 병렬 카드 이미지를 보강했다.
- `i18n/translations.ko.json`, `i18n/translations.ja.json`, `i18n/translations.en.json`에 `ua51` 시리즈명을 추가했다.
- `index.html`과 `docs/spec.md`의 버전 표기를 `v3.1.0`으로 통일했다.
- 다음 작업자가 동일한 기준으로 이어받을 수 있도록 `docs/codex-handoff.md`를 작성했다.
### 메모
- 이번 릴리즈는 신규 시리즈(`ua51`) 반영과 누락 자산 보강이 핵심이다.
- 배포 전에는 `datas/<series>.js`, `images/<series>/`, `i18n/translations.*.json` 세 축이 모두 맞물렸는지 반드시 함께 확인해야 한다.
- 이미지 자산은 계속 `Git LFS` 대상으로 유지한다.
## 2026-03-30 / docs-bootstrap-1
### 수행 작업
- 프로젝트 루트의 `.ai-rules.md`와 `.cursorrules`를 검토하여 문서 운영 규칙을 확인했다.
- 부재하던 `docs/` 디렉터리를 생성하고 문서 기본 세트(`update.md`, `todo.md`, `spec.md`, `convention.md`, `history.md`, `map.md`)를 초기 구축했다.
- 정적 사이트 구조를 기준으로 주요 페이지(`index.html`, `cardList.html`, `result.html`)와 보조 스크립트(`script/navigation.js`, `i18n/i18n.js`)의 역할을 문서화했다.
- 카드 데이터셋 구조(`datas/*.js`)와 이미지 경로 규칙(`images/<seriesKey>/<fileName>`)을 정리했다.
- 이미지 저장소 현황을 점검했다.
- 점검 결과: `images/` 디렉터리 약 `1.7G`, 이미지 파일 약 `9,370개`, 데이터 파일 `52개`.
- 대용량 이미지 자산 관리를 위한 `Git LFS` 도입 검토 사항과 주의점을 문서에 반영했다.
### 메모
- 현재 저장소에는 `docs/`가 없었기 때문에 이번 작업은 문서 체계 초기 세팅 성격이 강하다.
- `Git LFS`는 신규 이미지 유입 관리에는 유효하지만, 저장소 자체를 즉시 가볍게 만들지는 않으므로 히스토리 정리 전략을 별도 검토해야 한다.
## 2026-03-30 / lfs-migration-1
### 수행 작업
- `images/**` 전체를 `Git LFS` 대상으로 관리하기 위해 `.gitattributes`를 추가했다.
- 기존 저장소 용량 절감을 목표로 `Git LFS` 히스토리 마이그레이션을 수행하는 방향으로 결정했다.
- 현재 변경분을 포함한 뒤 전체 히스토리를 재작성하고 강제 푸시하는 절차를 진행한다.
### 메모
- 이번 작업은 단순 추적 설정이 아니라 과거 커밋까지 다시 쓰는 작업이므로 커밋 해시가 변경된다.
- 원격 반영 시 일반 푸시가 아닌 `force-with-lease`가 필요하다.
- 마이그레이션 체크아웃 이후 `ua27`의 추가 이미지와 데이터 보완분이 확인되어 최종 반영 대상에 포함했다.
## 2026-03-30 / repo-reset-1
### 수행 작업
- 저장소 용량을 근본적으로 단순화하기 위해 현재 로컬 작업본을 기준으로 새 루트 커밋 하나만 남기는 방향으로 전환했다.
- 기존 Git 히스토리는 원격 `main`에서는 제거하고, 로컬 백업 브랜치로만 보존하는 방식으로 진행한다.
- `images/**`는 계속 `Git LFS` 대상으로 유지한다.
- 새 시작 버전은 `v3.0.0`으로 정하고, 기존 `1.x`, `2.x` 버전 이력은 새 원격 기준에서 계승하지 않기로 했다.
### 메모
- 이 작업 후 원격 저장소는 사실상 "현재 스냅샷 기반 새 저장소"처럼 동작한다.
- 과거 커밋 이력, 기존 태그, 옛 해시는 원격 기준으로 더 이상 사용하지 않게 된다.
## 2026-03-30 / v3.0.1
### 수행 작업
- 일부 시리즈 데이터의 잘못된 이미지 경로를 실제 파일명 기준으로 수정했다.
- `ua04`, `ua30`, `ua37`, `ua38`, `ua45`의 `imgSrc` 오기입을 정정했다.
- `ua44`에서 더 이상 사용하지 않는 주석 처리된 `UAPR/EVA-AP01`, `UAPR/EVA-AP02` 항목을 제거했다.
- 누락되어 있던 이미지 파일 `images/ua08/UAPB_BLC-AP01.png`, `images/ua09/UAPR_BTR-AP03.png`를 반영했다.
### 메모
- 이번 반영은 카드 데이터와 실제 이미지 파일 간의 불일치를 줄이는 목적이다.
- 버전 태그 체계는 `v3.x` 기준으로 이어간다.