diff --git a/HANDOFF.md b/HANDOFF.md index be10680..9bb5030 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -4,7 +4,7 @@ - 프로젝트명: 10 Minute Planner 웹 UI - 기술 스택: Vue 3 + Vite + TailwindCSS + JavaScript -- 현재 기준 버전: `v0.1.21` 준비 중 +- 현재 기준 버전: `v0.1.22` 준비 중 - Git 원격 저장소: `https://git.sori.studio/zenn/planner.sori.studio.git` ## 기준 디자인 @@ -155,6 +155,9 @@ - `planner_entries.payload`는 문자열이 아니라 PostgreSQL `JSONB`로 저장되도록 바뀌었다. - `docker-compose.yml` 기준으로 `postgres`, `backend`, `frontend(nginx)` 3개 서비스 초안이 추가되었다. - 프론트는 nginx에서 `/api`를 백엔드로 프록시하는 구조라서, 배포 시 브라우저가 별도 API 포트를 직접 알 필요가 없다. +- 프론트 API 클라이언트는 `VITE_API_BASE_URL` 끝에 `/api`가 포함되어 있어도 `/api/api/...` 중복 주소가 생기지 않도록 정규화한다. +- 로그인 실패 시에는 내부 라우트 문자열이나 서버 경로를 그대로 노출하지 않고, 사용자용 안내 문구만 보여준다. +- 비로그인 상태에서는 왼쪽 사이드 내비게이션을 숨기고, 중앙 로그인 안내 화면만 보여주도록 정리했다. - 현재 환경에서는 Docker 데몬이 꺼져 있어서 `docker compose build` 실검증은 하지 못했고, 데몬 시작 후 다시 확인이 필요하다. - 이미지 저장 기능은 추후 `print-only` 또는 별도 export 전용 레이아웃을 기준으로 구현하면 화면/인쇄/공유 결과를 맞추기 쉽다. - Docker Compose는 프론트엔드와 백엔드를 함께 올리는 기준으로 설계하되, NAS 환경에 맞는 볼륨과 재시작 정책도 함께 고려한다. diff --git a/package-lock.json b/package-lock.json index 3f47455..0bf9613 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ten-minute-planner", - "version": "0.1.21", + "version": "0.1.22", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ten-minute-planner", - "version": "0.1.21", + "version": "0.1.22", "dependencies": { "vue": "^3.5.13" }, diff --git a/package.json b/package.json index 5f469cc..7a834b8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ten-minute-planner", "private": true, - "version": "0.1.21", + "version": "0.1.22", "type": "module", "scripts": { "dev": "vite", diff --git a/src/App.vue b/src/App.vue index ad2062a..dda9393 100644 --- a/src/App.vue +++ b/src/App.vue @@ -16,6 +16,7 @@ import { updatePassword, updateProfile, } from './lib/authClient' +import { toUserFacingApiError } from './lib/apiBase' import { createGoal, deleteGoal, fetchGoals, updateGoal } from './lib/goalsApi' import { deletePlannerEntry, fetchPlannerEntries, savePlannerEntry } from './lib/plannerApi' import { @@ -849,7 +850,7 @@ async function submitAuthForm() { await applyAuthSuccess(result) } catch (error) { - authMessage.value = error.message || '인증 처리 중 문제가 발생했습니다.' + authMessage.value = toUserFacingApiError(error, '인증 처리 중 문제가 발생했습니다.') } finally { authBusy.value = false } @@ -1296,8 +1297,14 @@ onMounted(() => {