# 업데이트 이력 ## 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 고정 이름 제약을 문서화 - Homepage 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`: 상단 설명 `

` 제거 → `?` 도움말 버튼 - `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`)로 인해 보이지 않던 문제 수정 - 페이지 내 `