feat(app): focus entry surface로 진입 화면 재구성

This commit is contained in:
2026-03-13 09:54:33 +09:00
parent 698c124ade
commit 2506dd53a7
16 changed files with 1346 additions and 30 deletions

View File

@@ -1,9 +1,76 @@
# 90. Current State
Last Updated: 2026-03-11
Last Updated: 2026-03-12
## DONE
- Focus Entry Surface / Execution Surface 재정의:
- `/app`을 planning home이 아니라 hero-first focus entry surface로 재구성
- 상단 카피를 `Planning Home` 톤에서 `지금 시작할 첫 블록` 진입 톤으로 교체
- 메인 hero에 one-line goal input + 단일 primary CTA `지금 시작`만 남기고, 첫 진입의 주 행동을 고정
- empty state에서는 starter draft를 자동 주입하지 않고 placeholder 입력으로 시작한다
- suggestion chip으로 draft를 빠르게 교체할 수 있게 하고, 직접 타이핑 시에는 ad-hoc start를 허용
- block CRUD는 메인 화면에서 제거하고 `블록 정리` manage sheet 안으로 내렸다
- `FocusPlan` current item은 hero prefill로 이어지고, preview row는 최대 2개까지만 보조적으로 노출
- Free는 1개, Pro는 최대 5개 블록까지 관리하도록 프론트 제한을 유지
- `/space`는 planning overview 없이 goal/scene/sound/timer + HUD 실행 화면으로 정리
- focus-plan / focus-session 서버 계약 연결:
- `GET /api/v1/focus-plan/today`
- `POST /api/v1/focus-plan/items`
- `PATCH /api/v1/focus-plan/items/:id`
- `DELETE /api/v1/focus-plan/items/:id`
- `POST /api/v1/focus-plan/items/:id/complete`
- `POST /api/v1/focus-sessions/current/advance-goal`
- frontend에서 plan item id와 today plan 응답을 backend contract 기준으로 정규화
- `GET /today`는 current 이후 pending item 전체를 `nextItems`로 반환
- 목표 완료 후 다음 목표 즉시 실행 흐름 구현:
- GoalCompleteSheet에서 다음 목표를 입력하면 현재 세션 완료 + 새 planning item 생성 + 다음 세션 즉시 시작
- 같은 scene / sound / timer를 유지한 채 `/space` focus 화면에서 그대로 이어감
- 실패 시 시트를 닫지 않고 HUD 토스트로 에러만 노출
- `/stats` factual summary 정리:
- weekly insight / quiet accountability mock 제거
- today / last7Days / trend만 남기고 factual card 구조로 단순화
- Calm Session OS 유료화 축 구현:
- Free는 기본 시작, Pro는 더 잘 이어가기를 파는 구조로 재정의
- old `Scene Packs / Sound Packs / Profiles` 중심 copy를 `Daily Focus Plan / Rituals / Weekly Review` 중심으로 교체
- `/app` route를 Session OS focus entry surface로 복구:
- `/app` route가 `/space` redirect 대신 `FocusDashboardWidget`을 렌더링
- current/next summary card와 list-first 구조를 제거하고, entry hero가 above-the-fold를 차지한다
- `start``plan persistence`와 분리해 goal only 쿼리로도 `/space` 진입 가능하게 정리했다
- Free에서 두 번째 블록 추가 시도 시 manage sheet 내부에서 paywall로 진입
- 플랜 tier 공유 store 추가:
- `entities/plan/model/usePlanTier.ts` 추가
- localStorage 기반 Free/Pro 상태를 `/app`, `/space`, `/stats`, dock paywall에서 공통 사용
- Session OS 도메인 mock 추가:
- `FocusPlanItem`
- `SessionTemplate`
- `SessionOutcome`
- `WeeklyReview`
- `AsyncCheckIn`
- `entities/session/model/focusSystem.ts`에 mock/헬퍼 집약
- `/space` planning overview 제거:
- setup drawer에서 Daily Plan / Ritual Library 진입 섹션 제거
- `/app`에서 넘긴 goal + `planItemId`를 받아 execution-only surface로 집중
- `/stats` factual summary 정착:
- 기존 API summary/trend 유지
- 해석형 insight/quiet accountability preview를 제거하고 factual card만 유지
- paywall / plan / landing 메시지 재정렬:
- paywall 가치 포인트를 multi-queue, rituals, weekly review 중심으로 재작성
- landing pricing에서 구현되지 않은 1:1 매칭 / 오픈 코워킹 / 팀 대시보드를 메인 판매 포인트에서 제거
- Teams는 후순위 준비중 톤으로 약화
- Gemini 분리본 재점검:
- `SpaceWorkspaceWidget`, `SpaceToolsDockWidget`, `admin/page.tsx`, `shared/i18n/ko.ts` 분리 상태를 다시 확인
- 현재 기준 500줄 초과 파일 없음
- 최대 파일은 `src/widgets/admin-console/ui/AdminDashboardView.tsx` 482줄
- `/admin` 업로드 콘솔 회귀 복구:
- widget 분리 이후 로그인 후 placeholder만 보이던 상태 제거
- `AdminConsoleWidget`은 조합만 담당하고, 실제 scene/sound 업로드 UI는 `AdminDashboardView`로 분리 복원
- 인증 전역 상태 위치 정리:
- `src/store/useAuthStore.ts` 제거
- `entities/auth/model/useAuthStore.ts`로 이동해 auth feature가 루트 store를 직접 참조하지 않도록 정리
- auth 타입 참조 정리:
- `features/admin/api/adminApi.ts``features/auth/types` 대신 `entities/auth`를 직접 사용
- `features/auth/types/index.ts`는 중복 선언을 제거하고 `entities/auth` 재export만 담당
- `/space` stage 배경 overscan 보정:
- pan 애니메이션 중 가장자리 빈틈이 드러나지 않도록 stage background layer를 `-inset-8`로 확장
- `/space` 배경 asset 해석 안정화:
@@ -17,12 +84,12 @@ Last Updated: 2026-03-11
- Quick Controls Time의 `90/20` 잠금을 제거
- 기본 Sound 잠금 제거로 Free에서도 기본 3~6 프리셋 선택 가능
- Pro 가치 재배치:
- Pro 잠금 대상을 `Scene Packs / Sound Packs / Profiles`로 재정의
- Pro 잠금 대상을 `Daily Focus Plan / Rituals / Weekly Review`로 재정의
- 기본 Scene/Time/Sound는 잠금 없이 선택 중심으로 정리
- Control Center UI 재구성:
- Scene/Time/Sound 중심 구조 유지
- 추천 조합을 정보 1줄로 축소(비인터랙션)
- 하단에 Packs/Profiles 요약 카드(작은 🔒 배지) 추가
- 하단에 Session OS 요약 카드(작은 🔒 배지) 추가
- Paywall 의도 기반 트리거 적용:
- 잠금 카드 클릭 시에만 Paywall Sheet 오픈
- Plan Pill(NORMAL) 클릭은 즉시 결제창 대신 상태 안내만 표시
@@ -159,12 +226,21 @@ Last Updated: 2026-03-11
## NEXT
1. `/space`에서 `forest` / `green-forest` manifest 변형을 실제 브라우저 기준으로 QA
2. Goal Complete Sheet 플로우(완료 → 다음 한 조각) 전환 감도/카피 마감
3. Stage 가독성/모션/레이어 폴리시 최종 통일
1. `/app` focus entry surface start/manage 브라우저 스모크
2. `/space` goal-complete -> next goal immediate start 흐름 QA
3. `/stats` factual summary / trend / refresh 브라우저 QA
## RISKS
- `/app` manage sheet의 리스트는 append-only라 drag/drop reorder는 아직 없다
- Free/Pro 제한은 클라이언트 local tier 기준이므로 서버에서 직접 막지 않는다
- Free/Pro gating은 localStorage mock tier 기반이라 실제 구독 상태와 연결되지 않았다
- `advance-goal`은 atomic endpoint 기준으로 동작하지만, 네트워크 실패 시 사용자는 현재 시트에서 재시도해야 한다
- Session OS 도메인은 mock 기반이므로 실제 저장/복구 API 없이도 화면만 먼저 완성된 상태다
- empty state에서 CTA는 살아 있지만 실제 시작 전에 입력 포커스가 먼저 필요하므로, 첫 진입 사용성은 브라우저 확인이 필요하다
- current item이 아닌 preview row 선택은 ad-hoc start로 처리되므로, 큐 재정렬을 기대하는 사용자와 정신 모델 차이가 생길 수 있다
- `/space` paywall 전환 진입점은 `/app` / `/stats` 중심이라 execution 화면만 본 사용자에게는 업그레이드 맥락이 약할 수 있다
- `/admin` 업로드 콘솔은 구조 복구가 끝났지만, 실제 파일 업로드 경로는 브라우저 수동 검증 전까지 확정할 수 없다
- stage background overscan으로 좁은 화면에서 배경 crop이 조금 더 강하게 느껴질 수 있어 실기기 확인이 필요하다
- remote manifest 실패 시 원인 진단은 가능해졌지만, 사용자용 복구 액션 UI는 아직 없다
- alias 목록에 없는 legacy scene id가 추가되면 같은 fallback 문제가 재발할 수 있다
@@ -191,11 +267,38 @@ Last Updated: 2026-03-11
## CHANGED FILES
- (이번 구조 재점검)
- `src/widgets/admin-console/ui/AdminConsoleWidget.tsx`
- `src/widgets/admin-console/ui/AdminDashboardView.tsx`
- `src/features/admin/api/adminApi.ts`
- `src/features/auth/types/index.ts`
- `src/entities/auth/index.ts`
- `src/entities/auth/model/useAuthStore.ts`
- `src/features/auth/hooks/useSocialLogin.ts`
- `src/features/auth/components/AuthRedirectButton.tsx`
- `docs/02_arch_fsd_rules.md`
- `docs/work.md`
- `docs/90_current_state.md`
- `docs/session_brief.md`
- (이번 세션)
- `src/app/(app)/app/page.tsx`
- `src/widgets/focus-dashboard/ui/FocusDashboardWidget.tsx`
- `src/widgets/focus-dashboard/ui/FocusPlanManageSheet.tsx`
- `src/widgets/focus-dashboard/ui/FocusPlanListRow.tsx`
- `src/entities/focus-plan/model/useFocusPlan.ts`
- `src/widgets/focus-dashboard/index.ts`
- `src/entities/plan/model/usePlanTier.ts`
- `src/entities/session/model/focusSystem.ts`
- `src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx`
- `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`
- `src/widgets/stats-overview/ui/StatsOverviewWidget.tsx`
- `src/shared/i18n/messages/core.ts`
- `src/shared/i18n/messages/app.ts`
- `src/shared/i18n/messages/product.ts`
- `src/shared/i18n/messages/space.ts`
- `src/entities/media/model/types.ts`
- `src/entities/media/model/resolveMediaAsset.ts`
- `src/entities/media/model/useMediaCatalog.ts`
- `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`
- `docs/work.md`
- `docs/90_current_state.md`
- `docs/session_brief.md`

View File

@@ -1,6 +1,6 @@
# Session Brief
Last Updated: 2026-03-11
Last Updated: 2026-03-12
세션 시작 시 항상 읽는 초소형 스냅샷 문서.
@@ -14,14 +14,50 @@ Last Updated: 2026-03-11
## 현재 우선순위
1. `/space` forest 배경이 `forest` / `green-forest` manifest key 모두에서 동일하게 붙는지 브라우저 QA
2. Goal Complete Sheet 플로우(완료 → 다음 한 조각) 마감 품질 점검
3. Stage 가독성/모션/레이어 폴리시 최종 정리
1. `/app` focus entry surface start/manage 브라우저 QA
2. `/space` goal-complete -> next goal immediate start 흐름 QA
3. `/stats` factual summary / trend / refresh QA
## 최근 세션 상태
- `/app`을 planning home이 아니라 focus entry surface로 다시 재구성했다.
- hero에 one-line goal input과 단일 CTA `지금 시작`을 두고, 첫 블록 진입을 화면의 주 행동으로 올렸다.
- empty state에서는 값을 미리 채우지 않고 placeholder만 두며, 입력 후 바로 `/space`로 들어간다.
- suggestion chip으로 draft를 빠르게 바꿀 수 있고, 직접 수정하면 ad-hoc start가 가능하다.
- plan CRUD는 메인 화면에서 제거하고 `블록 정리` manage sheet 안으로 내렸다.
- current item은 hero를 prefill하고, next item은 최대 2개까지만 얕은 preview로 남긴다.
- Free는 1개, Pro는 최대 5개까지 관리한다.
- `/space`는 execution-only surface로 정리됐다.
- setup drawer에서 Daily Plan / Ritual Library 섹션을 제거했다.
- goal, scene, sound, timer만 확인하고 focus HUD로 진입한다.
- 목표 완료 후 다음 목표 즉시 실행 흐름이 backend contract와 연결됐다.
- GoalCompleteSheet confirm 시 `advance-goal` endpoint를 사용한다.
- 현재 세션 완료, linked plan item 완료, 새 current item 생성, 다음 세션 시작을 한 번에 처리한다.
- 실패 시 시트를 닫지 않고 그대로 재시도할 수 있다.
- `/stats`는 해석형 review 화면이 아니라 factual summary로 정리됐다.
- today / last7Days / trend만 유지한다.
- started/completed/carried over/focus minutes 중심으로 표시한다.
- 유료화 포지셔닝을 `Calm Session OS`로 재정의했다.
- Free는 기본 집중 시작, Pro는 더 잘 이어가기라는 메시지로 정리했다.
- old `Scene Packs / Sound Packs / Profiles` 중심 카피를 `Daily plan / Rituals / Weekly review` 구조로 교체했다.
- `/app`은 더 이상 `/space` redirect가 아니다.
- `FocusDashboardWidget`에서 goal only start와 plan-linked start를 모두 처리한다.
- Free에서 두 번째 블록 추가 시도는 manage sheet 안에서 paywall로 진입한다.
- 플랜 tier를 route 간에 공유하도록 정리했다.
- `usePlanTier` localStorage store를 추가해 `/app`, `/space`, `/stats`가 같은 Free/Pro 상태를 본다.
- Session OS mock 도메인을 추가했다.
- `FocusPlanItem`, `SessionTemplate`, `SessionOutcome`, `WeeklyReview`, `AsyncCheckIn` 모델과 mock 데이터를 `entities/session`에 추가했다.
- `/space` stage 배경을 overscan으로 보정했다.
- background layer를 `-inset-8`로 확장해 pan 애니메이션 중 가장자리 빈틈 노출을 줄였다.
- Gemini가 진행한 대형 파일 분리를 다시 점검했다.
- `SpaceWorkspaceWidget`, `SpaceToolsDockWidget`, `admin/page.tsx`, `shared/i18n/ko.ts` 모두 500줄 기준 안으로 정리된 상태를 재확인했다.
- 현재 주요 최대 파일은 `AdminDashboardView.tsx` 482줄, `useSpaceWorkspaceSelection.ts` 440줄 수준이다.
- `/admin` 분리 과정의 placeholder 회귀를 복구했다.
- 로그인 후 `Dashboard is under construction`만 보이던 상태를 제거했다.
- 실제 scene/sound 업로드 폼을 `AdminDashboardView`로 복원해 `AdminConsoleWidget`은 조합만 담당하도록 되돌렸다.
- 인증 전역 저장소 위치를 정리했다.
- `src/store/useAuthStore.ts`를 제거했다.
- 인증 상태 저장소를 `entities/auth/model/useAuthStore.ts`로 이동해 feature가 루트 store를 직접 참조하지 않도록 정리했다.
- `/space` 배경 asset 해석을 보강했다.
- media manifest scene key를 alias-aware 하게 정규화해 `green-forest``forest`를 같은 scene asset으로 읽는다.
- scene/sound asset에 `source(fallback|remote)` 메타를 추가해 remote asset 사용 여부를 코드에서 바로 식별할 수 있다.
@@ -32,11 +68,11 @@ Last Updated: 2026-03-11
- 기본 기능 잠금을 해소했다.
- Time `90/20`을 Free로 개방
- 기본 Sound 잠금 제거
- Pro 잠금 구조를 Packs/Profiles 중심으로 재구성했다.
- `Scene Packs / Sound Packs / Profiles` 요약 카드 추가
- Pro 잠금 구조를 Session OS 중심으로 재구성했다.
- `Daily Focus Plan / Rituals / Weekly Review` 요약 카드 추가
- 기본 Scene/Time/Sound는 잠금 없이 선택 가능
- Paywall 시트는 잠금 카드 클릭에서만 열리도록 바꿨다.
- Plan Pill(NORMAL) 클릭은 즉시 결제창 오픈 대신 상태 안내만 노출
- Plan Pill(FREE) 클릭은 즉시 결제창 오픈 대신 상태 안내만 노출
- Paywall 카피를 3개 가치 포인트 + 2개 CTA로 간결화
- Focus-First 구조로 전환했다.
- Quick Controls의 모드 전환 토글(기본/몰입)을 제거했다.
@@ -120,8 +156,13 @@ Last Updated: 2026-03-11
## 리스크
- Session OS 데이터는 아직 mock 기반이므로 실제 저장/동기화 API 없이도 화면이 그럴듯하게만 보일 수 있다.
- empty state에서 CTA는 유지하지만 실제 시작 전에 입력 포커스가 먼저 필요하므로, 첫 진입 사용성은 브라우저 확인이 필요하다.
- current item이 아닌 preview row 선택은 ad-hoc start로 처리되므로, 큐 재정렬을 기대하는 사용자와 정신 모델 차이가 날 수 있다.
- `/space` paywall 전환 진입점은 `/app` / `/stats` 중심이라 execution 화면만 본 사용자에게는 업그레이드 맥락이 약할 수 있다.
- stage background overscan으로 좁은 화면에서 배경 crop 체감이 조금 더 커질 수 있다.
- remote manifest 실패 시 원인 진단은 가능하지만, 사용자용 복구 CTA는 아직 없다.
- `/admin` 업로드 콘솔은 타입/구조상 복구됐지만 실제 브라우저 업로드 스모크는 아직 필요하다.
- alias 목록에 없는 legacy scene id가 다시 들어오면 scene fallback 문제가 재발할 수 있다.
- 네트워크 제한 환경에서는 `npm run build` 시 Google Fonts fetch 실패 가능
- localStorage 저장 포맷 변경 시 이전 세션 데이터와의 호환성 이슈가 생길 수 있음

View File

@@ -17,21 +17,62 @@
## 작업 1
- 제목: Space 배경 QA - forest / green-forest manifest 변형 검증
- 제목: Focus Entry Surface /space linked flow 브라우저 QA
- 목적:
- 최근 적용한 scene alias/fallback 보강이 실제 브라우저에서 기대대로 동작하는지 확인한다.
- `forest``green-forest` 두 manifest 변형 모두에서 같은 배경이 표시되는지 검증한다.
- `/app`이 planning home이 아니라 focus entry surface로 보이는지 확인한다.
- hero input + primary CTA만으로 `/space` 진입이 가능한지 검증한다.
- 변경 범위:
- 로컬 또는 스테이징 환경에서 `/space?scene=forest` 진입 확인
- manifest의 `sceneId=forest` / `sceneId=green-forest` 두 경우 모두 동일 배경 적용 확인
- manifest 실패 시 HUD 메시지/console 진단 로그 노출 확인
- `/app` hero input / placeholder / suggestion chip / start CTA 확인
- `블록 정리` sheet 열기, row 선택, row 수정, row 삭제 확인
- Free 1개 / Pro 5개 제한 확인
- 제외 범위:
- 추가 코드 수정 금지
- R2 업로드 파이프라인 수정 금지
- 실제 결제 연동 금지
- calendar/task 외부 연동 금지
- 완료 조건:
- 두 scene key 변형 모두에서 같은 forest 배경이 노출된다.
- manifest 실패 시 조용한 fallback만 남지 않고 진단 정보가 확인된다.
- `/app`이 리스트 CRUD보다 `지금 시작` hero가 먼저 읽힌다.
- empty state에서도 disabled primary CTA 없이 `/space` 진입 경로가 살아 있다.
- manage sheet 안에서만 add/edit/delete가 보이고, 메인 화면에는 row-level 관리 버튼이 없다.
- start link에 담긴 goal/plan item이 `/space` 세션 시작까지 유지된다.
- 검증:
- 브라우저 수동 확인
- 커밋 힌트:
- chore(qa): space 배경 alias/fallback 브라우저 검증
- chore(qa): focus-entry-surface smoke
## 작업 2
- 제목: 목표 완료 후 다음 목표 즉시 실행 QA
- 목적:
- `/space`가 execution-only surface로 보이는지 확인한다.
- goal complete sheet에서 다음 목표를 입력하면 setup으로 돌아가지 않고 즉시 다음 세션이 시작되는지 검증한다.
- 변경 범위:
- `/space?goal=...&planItemId=...` 진입 확인
- goal complete -> next goal -> running session 전환 확인
- scene/sound/timer 유지 여부 확인
- 제외 범위:
- timer 종료 자동 전환 추가 금지
- ritual/template persistence 추가 금지
- 완료 조건:
- 현재 목표 완료 시 linked plan item이 완료 처리되고, 새 목표가 즉시 running session으로 이어진다.
- `/space` setup drawer에 planning/ritual 섹션이 남아 있지 않다.
- 검증:
- 브라우저 수동 확인
- 커밋 힌트:
- chore(qa): advance-goal linked session smoke
## 작업 3
- 제목: `/stats` factual summary QA
- 목적:
- `/stats`가 해석형 insight 없이 factual summary만 보여주는지 확인한다.
- 변경 범위:
- today / last7Days factual cards 확인
- trend 그래프와 refresh/source 상태 확인
- 제외 범위:
- 해석형 패턴 추천 추가 금지
- social/accountability mock 복구 금지
- 완료 조건:
- `/stats`에서 started/completed/carried over/focus minutes만 일관되게 보인다.
- 검증:
- 브라우저 수동 확인
- 커밋 힌트:
- chore(qa): stats factual summary smoke