feat(flow): focus session api v2 웹 계약 전환

This commit is contained in:
2026-03-16 17:30:52 +09:00
parent f4910238a0
commit 38abc1e0c7
30 changed files with 390 additions and 702 deletions

View File

@@ -8,7 +8,9 @@ Last Updated: 2026-03-16
- `Slice 1` no-session shell 구현 완료
- `Slice 1-2` visual premium polish 구현 완료
- `Custom Duration Contract``Weekly Review Dock Reposition`은 다음 slice로 남아 있음
- `Custom Duration Contract` 구현 완료
- `Weekly Review Dock Reposition` 구현 완료
- 다음 slice는 `/space` current-session-only cleanup과 browser QA다
핵심 정책 변경:
@@ -256,7 +258,7 @@ Last Updated: 2026-03-16
### E. Selection Rules
- no-session 상태에서는 atmosphere 1개가 기본 선택된 상태로 시작한다
- review handoff로 들어온 경우에는 handoff preset과 가장 가까운 atmosphere를 preselect한다
- review handoff로 들어온 경우에는 handoff `entryAtmosphereId + entryDurationMinutes`를 preselect한다
- 사용자가 duration을 직접 수정하기 전까지는 선택된 atmosphere의 기본 duration suggestion을 보여줄 수 있다
- 사용자가 duration을 직접 수정한 뒤에는 atmosphere를 바꿔도 duration 값을 덮어쓰지 않는다
@@ -397,31 +399,31 @@ Last Updated: 2026-03-16
---
## 10. Slice 1 구현 원칙
## 10. 구현 상태와 남은 작업
이번 구현 slice는 `/app`**no-session shell**을 먼저 바꾸는 단계다.
현재 `/app`의 no-session shell은 이미 구현되어 있고, focus-session API V2도 함께 연결됐다.
포함:
현재 포함된 범위:
- goal input
- duration input
- 12개 atmosphere grid
- selected atmosphere 기반 background 반영
- quiet review dock의 기본 위치
- raw `focusDurationMinutes` start payload
- review handoff의 `entryAtmosphereId + entryDurationMinutes`
제외:
이번 라운드에서 제외된 것:
- current session routing 재설계
- `/stats` IA 변경
- server custom duration contract
- `/space` current-session-only dead path cleanup
### Slice 1 임시 계약
### 현재 계약
- 사용자는 분 단위 duration을 입력한다
- 하지만 server contract가 아직 preset 기반이면, 이번 slice에서는 **입력 시간에 가장 가까운 기존 focus preset**으로 임시 매핑한
- 이 임시 매핑은 다음 slice(`Custom Duration Contract`)에서 실제 duration 연동으로 대체한
- UI에는 이 상태가 과장 없이 드러나야 한
- 예: `지금은 가장 가까운 기본 리듬으로 먼저 들어가요.`
- server`focusDurationMinutes`를 공식 start 계약으로 받는
- selected atmosphere는 `atmosphereId + sceneId + soundPresetId`로 함께 저장된
- `/space`는 current session 응답의 `focusDurationSeconds`, `atmosphereId`, `sceneId`, `soundPresetId`를 source of truth로 읽는
---
@@ -486,19 +488,10 @@ Last Updated: 2026-03-16
### 필요한 변화
1. `startSession`custom duration minutes를 받도록 확장
2. session에 `focusDurationMinutes` 저장
3. break duration 계산 정책 정의
4. atmosphere 선택 단위를 위한 `sceneId + soundPresetId` 조합 저장
### break duration 정책 제안
- 10~30분: 5분
- 31~60분: 10분
- 61~120분: 15분
- 121분 이상: 20분
이건 사용자가 break를 직접 고르지 않아도 자연스럽게 이어지게 하기 위한 기본 정책이다.
1. `startSession``focusDurationMinutes`를 공식 필드로 받는다
2. session에 `focusDurationSeconds``atmosphereId` 저장한다
3. `GET /focus-sessions/current``/space` hydration에 필요한 goal / duration / atmosphere / scene / sound를 모두 반환한다
4. `/stats -> /app` handoff는 preset이 아니라 atmosphere / duration 힌트를 사용한다
---

View File

@@ -266,7 +266,7 @@ Weekly Review는 `/stats` 안에서 아래 5개 구역으로 재구성한다.
예시:
- `Forest · 50/10에서 가장 오래 이어졌어요.`
- `Forest Draft · 50에서 가장 오래 이어졌어요.`
- `Rain 계열에서는 pause 후 복귀가 더 높았어요.`
중요:
@@ -400,7 +400,7 @@ Free에서 하지 않는 것:
- multi-week trend
- ritual 비교표
- scene/sound/timer 조합 비교
- atmosphere/duration 조합 비교
- archive 기반 long-term pattern
Free 가치:
@@ -471,7 +471,7 @@ trigger:
teaser 예시:
- `이번 주 pause 뒤 복귀가 3번 있었어요`
- `Forest 50/10에서 가장 잘 이어졌어요`
- `Forest Draft 50분에서 가장 잘 이어졌어요`
CTA:
@@ -482,7 +482,7 @@ CTA:
weekly review 마지막 CTA:
- `이 조합으로 다음 세션 시작`
- `/app`으로 연결하되 ritual preset을 prefill
- `/app`으로 연결하되 atmosphere와 duration을 prefill
즉 review는 읽고 끝나는 화면이 아니라 다음 entry에 연결돼야 한다.