시작: 2026-05-11 · 입력 근거: docs/discovery/competitor-screen-analysis-2026-05-11.md (경쟁앱 해부 + 화면별 권고)
산출물: 화면당 1파일, 아래 7섹션 고정 구조. 시각 목업은 docs/design/mockups/screens.html.
이 문서들은 구현 명세다.
lib/app/router.dart의 실제 라우트,lib/core/theme/tokens.dart의 토큰,docs/design/templates/의 카드 명세,docs/discovery/error-handling.md의 에러 분류,docs/db-schema.md의 스키마,docs/app-scenarios.md의 V1 동선을 단일 진실로 참조한다. 모순이 보이면 코드 쪽이 우선 — 문서를 고친다.
| 그룹 | 화면 | 라우트 | 구현 상태 | 실제 파일 | 설계 문서 |
|---|---|---|---|---|---|
| 2 | 홈 (내 인용 피드) | / |
✅ 구현 (PR3) | lib/features/home/home_screen.dart · quote/state/quote_feed_provider.dart · quote/presentation/widgets/quote_list_card.dart |
home.md |
| 1 | 인용구 입력 | /quote/new[?bookId=] |
✅ 구현 (PR2) | lib/features/quote/quote_input_screen.dart · data/quote_draft.dart · presentation/widgets/mood_chips.dart |
quote-input.md |
| 1 | 인용구 목록 (서재 “인용구” 세그먼트) | /library?tab=quotes[&mood=] |
✅ 구현 (PR4) | lib/features/quote/presentation/quote_list_view.dart (서재 화면 내 탭) |
quote-list.md |
| 3 | 서재 (책↔인용구 세그먼트) | /library |
✅ 구현 (PR4) | lib/features/library/library_screen.dart |
library.md |
| 2 | 내 정보 (프로필·내보내기·약관·탈퇴) | /me |
✅ 구현 (PR5) | lib/features/me/{me_screen.dart, state/me_providers.dart, data/{markdown_exporter,quote_export}.dart} · lib/features/account/account_deletion.dart · supabase/functions/delete-account/ (배포 미완) |
me.md |
| 2 | 책 상세 | /book/:id |
🟡 부분 — read-only + 별점(user_books.rating). “이 책에서 모은 N구절”·”인용구 추가” CTA·설명 점진공개·isInLibrary = PR6 |
lib/features/book/book_detail_screen.dart · presentation/widgets/star_rating.dart |
book-detail.md |
| 1 | 받은 카드 → 책 담기 (deep link 진입) | /book/:id?from=share |
🟡 부분 — /book/:id read-only만. from=share 분기 + deep_link_handler 일반화 = PR6 |
lib/app/deep_link_handler.dart (현재 /auth/callback만 처리) |
deep-link-receive.md |
| 1 | 카드 에디터 | /quote/:id/card |
⏳ 스텁 — Stage 3 | lib/features/card_editor/card_editor_screen.dart (스텁) |
card-editor.md |
| 1 | 카드 공유·저장 시트 | (모달, 카드 에디터에서) | ⏳ 없음 — Stage 3 | — | card-share.md |
| 3 | 스플래시 | /splash |
✅ 구현 (Stage 1) | lib/app/splash_screen.dart |
splash.md |
| 3 | 로그인 | /auth/login |
✅ 구현 (Stage 1) | lib/features/auth/login_screen.dart · auth_controller.dart |
login.md |
| 3 | 인증 콜백 | /auth/callback · /callback |
✅ 구현 (Stage 1) | lib/features/auth/auth_callback_screen.dart |
auth-callback.md |
| 3 | 책 검색 시트 | (모달, 서재·인용입력에서) | ✅ 구현 (Stage 1) | lib/features/book/presentation/book_search_sheet.dart |
book-search-sheet.md |
| 4 | 친구 프로필 (공개 책+공개 인용구 read-only) | /u/:userId |
⏳ 명세 — PR18-C 예정 | (예정) lib/features/profile/friend_profile_screen.dart |
friend-profile.md |
✅ 구현·동작 / 🟡 일부 구현(다음 PR에서 보강) / ⏳ 스텁·미구현(Stage 3 또는 명세만). 라우트·구조 진실 = lib/app/router.dart. 동선 = docs/app-scenarios.md. 그룹 4(소셜) = DECISIONS 2026-05-17 친구 서재 탐험 V1.0 합류로 신설.
화면 설계 문서 13개 1차 작성 완료(2026-05-12). 그룹 3 역정리 문서들은 §7에 “현행 동작”(코드 기준) + “수정·보강 권고”를 분리해 담았는데, 그 권고 상당수는 Stage 2 PR1~5에서 함께 처리됨(raw
$e노출 제거, 잘못된 “서재 추가” 토스트 제거,me_screen빈onTap·긴 이메일 오버플로 등). 남은 권고·버그는 각 문서 §7 +docs/STAGES.md백로그 + 세션 로그(docs/sessions/2026-05-12-screen-design-b.md~2026-05-14-stage2-pr5.md).
/splash ──(세션 있음)──▶ ┌─────────── StatefulShellRoute (BottomNav 4슬롯) ──────────┐
│ ✅ │ [0] / 홈 — 내 인용 피드 ✅ │
└─(없음)─┐ │ [1] /library 서재 — [책↔인용구] 세그먼트 ✅ │
│ │ [2] (+ sentinel) ──push──▶ /quote/new (풀스크린, 셸 밖) │
/auth/login ◀─┤ ✅ │ [3] /me 내 정보 — 프로필·내보내기·약관·탈퇴 ✅ │
│ ✅ │ └────────────────────────────────────────────────────────────┘
/auth/callback│ 풀스크린 (rootNavigatorKey, 셸 밖):
/callback ✅ │ /quote/new[?bookId=] 인용구 입력 (직접 입력 / 클립보드 붙여넣기) ✅
│ └─ "카드 만들기 →" ──push──▶ /quote/:id/card 카드 에디터 ⏳ 스텁(Stage 3)
게스트 허용 ◀─┘ └─ "공유" ──▶ 공유·저장 시트(모달) ⏳
/book/:id[?from=&sender=] ✅ read-only(+친구 N명·sender 배너 ⏳ PR18-D) └─ 카카오톡 → 받는 사람 ⏳
▲
└── 받는 사람 deep link: io.github.tgparkk.bookquote://book/:id?from=share&sender=<uid> ⏳ deep_link_handler 일반화 + sender 파싱(PR6+PR18-D)
├─ 로그인됨 → 책 상세 + "내 서재 담기" 1탭 + [이 사람 서재 ▸](sender 공개 프로필이면)
└─ 미로그인 → 책 상세 read-only → "담기" → /auth/login → 복귀해서 담기
/u/:userId ⏳ 친구 프로필 (PR18-C) — 공개 책 + 공개 인용구 read-only, [팔로우/언팔로우]
진입 = Me 친구찾기·책상세 친구 미니리스트·카드 deep link sender 배너·팔로잉/팔로워 시트
본인 자신 진입 → context.go('/me') redirect
모달 시트(어느 셸 탭에서도): showBookSearchSheet (알라딘 검색 + 캐시 사전조회) ✅
showFriendSearchSheet (profiles.display_name ilike) ⏳ PR18-B
✅ 구현 / ⏳ 스텁·미구현(다음 PR 또는 Stage 3). 탭 구조·풀스크린 규칙·게스트 라우트는 DECISIONS.md 2026-05-10 (go_router 구조) + lib/app/router.dart가 진실. 홈 = “내 인용 피드”(DECISIONS 2026-05-12 — “받은 카드 함”·follow 타임라인 합류는 V1.5). 서재 책 카드 “N구절 배지”·”표지색 띠”는 STAGES 백로그.
*.md 공통)screens.html의 해당 목업과 1:1.error-handling.md의 분류(Network/Auth/Validation/Business/External/Storage × Inline/Toast/Modal/Empty)로 기술. 각 상태에 심각도.tokens.dart의 색/간격/타이포/radius/shadow를 영역별로. 새 토큰 필요 시 명시.BookCover, showBookSearchSheet, _DragHandle 등)과 provider, 신규로 만들 것.competitor-screen-analysis §6의 공통 8원칙 적용 + 화면 고유 엣지 + 대비(WCAG AA 4.5:1) / 터치 타깃 48dp / 스크린리더 semantics / 색만으로 구분 금지.competitor-screen-analysis §6)/quote/new·/quote/:id/card 등 쓰기 화면은 go_router redirect 차단 + repository NOT_AUTHENTICATED 2차 방어; /book/:id는 게스트 허용 — deep link용)testing-strategy.md §6)deep_link_handler 일반화) → Stage 3(카드 에디터·공유·deep link 받기 — 가장 공들일 단계). 상세는 docs/STAGES.md “▶ 다음 세션 시작점” + 세션 로그.listMyQuotes cursor 시그니처 확정 / 책 별점 = user_books.rating 정수 1~5.supabase/functions/delete-account/ 작성 완료, 배포 미완(npx --yes supabase functions deploy delete-account) ② 개인정보처리방침·이용약관 호스팅 페이지 — me_screen.dart 링크는 연결됐으나 URL placeholder ③ cards 등 V1.5 새 테이블에 on delete cascade auth.users(또는 quotes) 챙기기. (quotes/user_books/profiles는 이미 cascade — docs/db-schema.md §4.)