웹 고도화 (데모/프리뷰 + Web Push + PWA)
권위: decision-log.md · deploy-checklist.md · AGENTS.md.
실행 추적 ID: N4-W0 … N4-W7 (deploy-checklist.md §N4-W).
0. 고정 결정 (2026-08-04 Master)
| # |
결정 |
상태 |
| 1 |
웹 = 데모/프리뷰 1차 표면 (https://msn.iykyka.com). Android 동등 교체 아님 |
확정 |
| 2 |
Web Push(FCM Web + VAPID) · PWA(설치·standalone·셸 SW) 포함 |
확정 |
| 3 |
본 문서로 Wi를 완전 상세히 짜고, Wi 단위로 차근차근 구현 |
확정 |
| 4 |
Q9(L2 수신 트리거 자동응대) · PoC §3 기본값 추측 · L3/OS/B2B 비범위 |
확정 |
성공 정의 (데모/프리뷰)
두 테스터가 브라우저만으로: 가입(또는 로그인) → 사용자 ID 교환·연락처 → 대화 → 초안(✨) → L1 승인·와카뷰 뱃지 → 설정/로그아웃까지 안정 시연.
비범위 (전체 공통)
- Q9 수신 트리거 자동응대 및 “자리를 비우면 알아서 답함” 카피
- 사람 PoC #1/#3 실행 · 자율성/화이트리스트 기본값 확정
- Android N4 실기기 트랙(병행 가능, 본 문서 작업 분해에 넣지 않음)
- Drift WASM / SQLCipher-on-web / Play·App Store 배포
- 계정 삭제 UI (Q8e), 이미지·읽음·타이핑 등 일반 메신저 확장
구현 규율
- 한 번에 W 전체 구현 금지.
Wi마다 Master 승인 → 코드 → 본 문서·deploy-checklist Status 동시 갱신.
- Wi 완료 전 다음 Wi 착수하지 않는다 (의존 화살표 준수). 예외는 Master 명시.
- 시크릿(Firebase Web config, VAPID, 서비스 계정) git 커밋 금지.
- 서버 FCM HTTP v1 SA는 Android N4와 공유. 클라이언트 시크릿 경로만 플랫폼별 분리.
flowchart LR
W0[W0_Boundary] --> W1[W1_Persistence]
W1 --> W2[W2_DemoUX]
W2 --> W3[W3_InAppNotify]
W3 --> W4[W4_WebPush]
W4 --> W5[W5_PWA]
W5 --> W6[W6_TesterOps]
W6 --> W7[W7_Quality]
1. As-is (코드 박제, 2026-08)
| 영역 |
현황 |
근거 |
| 서빙 |
Flutter web + nginx, API/WS 프록시 |
mobile/Dockerfile, deploy/nginx-web.conf |
| 로컬 DB |
웹 = 메모리 스텁, 새로고침 시 말투·온보딩·스누즈 유실 |
mobile/lib/db/app_database_web.dart |
| 세션 |
shared_preferences에 user/token (웹에서도 대체로 유지) |
mobile/lib/state/session_state.dart |
| 푸시 |
웹에서 FCM 즉시 skip → install: 플레이스홀더 |
mobile/lib/services/push_token_service.dart |
| 스누즈 OS 알림 |
웹 no-op |
mobile/lib/services/snooze_notification_service_web.dart |
| PWA 골격 |
manifest.json + icons 있음. theme #7C6FF0(낡은 아우로라). SW 전략 미문서화 |
mobile/web/ |
| 서버 푸시 |
HTTP v1 SA 마운트됨. 플레이스홀더 토큰은 skip |
core-backend/push.go, /admin/push-test |
| 테마 |
iMessage-inspired light + soft charcoal dark |
mobile/lib/theme/app_theme.dart (#007AFF / canvas #F2F2F7·#141418) |
N4-W0 — 제품 경계
|
|
| Status |
done (본 문서 랜딩으로 경계 고정, 2026-08-04) |
| 목표 |
웹 고도화의 제품·기술 경계를 문서에 고정해 구현 범위 논쟁을 없앤다 |
| 비범위 |
코드 변경 없음 |
작업 분해
수락 기준
Master 액션
위험
- “웹도 Android만큼”으로 범위가 커지면 W1에서 Drift WASM 등으로 비대화 → §0을 인용해 거절
터치 파일 (문서)
docs/web-upgrade.md (본 파일)
README.md, docs/roadmap.md, docs/deploy-checklist.md, docs/fcm-setup.md, mobile/README.md
N4-W1 — 웹 로컬 지속성
|
|
| Status |
done (2026-08-04) |
| 목표 |
하드 리프레시 후에도 말투·온보딩·스누즈·install id가 유지되는 프리뷰 UX |
| 비범위 |
SQLCipher/암호화 DB, Drift WASM, 서버 측 말투 동기화 |
As-is
AppDatabase 웹 구현이 in-memory Map (app_database_web.dart)
- 인증만
SharedPreferences에 남아 새로고침 후 “가입된 것처럼” 보이지만 말투 온보딩이 다시 뜰 수 있음
To-be
- 웹
AppDatabase를 durable KV로 승격
- 기술 선택 (고정):
shared_preferences(또는 동일 idb 백엔드)로 KV·말투 JSON·스누즈 맵 직렬화. Drift WASM 비채택
encrypted 플래그는 웹에서 계속 false; DataFlowScreen 카피에 “웹 프리뷰는 브라우저 저장소(비암호화)” 명시
작업 분해
수락 기준
Master 액션
위험
- prefs 용량·JSON 파싱 오류 시 빈 DB로 폴백 (corrupt 시 wipe + 로그)
- 여러 탭 동시 기록 → last-write-wins 허용 (프리뷰)
예상 터치 파일
mobile/lib/db/app_database_web.dart
mobile/lib/screens/data_flow_screen.dart (카피)
mobile/test/ (웹 persistence 테스트, 선택)
docs/web-upgrade.md Status → done
N4-W2 — 데모 메신저 UX
|
|
| Status |
done (2026-08-04) |
| 목표 |
데스크톱·모바일 브라우저에서 시연 마찰을 줄인 프리뷰 UX |
| 비범위 |
디자인 시스템 전면 교체, 카드/히어로 과설계, Q9 카피 |
As-is
- 모바일 우선 단일 컬럼 스택; 대화 목록 ↔ 채팅 push
MyUserIdChip 등 ID 노출은 있으나 페어링 CTA 발견성 편차
- WS 재연결 backoff는 구현됨, UI 인디케이터는 약함
To-be
- 넓은 뷰포트(예: ≥900px): 목록 | 채팅 분할(또는 동등 반응형). 좁은 폭은 기존 스택 유지
- WS 연결 상태: connecting / live / reconnecting(backoff) 한 줄 표시
- 내 사용자 ID 원탭 복사 CTA 강화 (대화 목록·설정)
- 웹 기대치 배너(첫 진입 또는 설정): 새로고침 후 데이터(W1 이후), 알림(W3/W4), 홈 화면 추가(W5)
- 시각: 기존 iMessage-inspired 테마 유지. 신규 카드 남발·히어로 오버레이 금지
작업 분해
수락 기준
Master 액션
- UX 톤 승인 (분할 vs 스택-only 미세 조정은 구현 PR에서 스크린샷)
위험
- Navigator 스택과 분할 레이아웃 충돌 → 웹만
MasterDetail 패턴으로 격리
예상 터치 파일
mobile/lib/main.dart
mobile/lib/screens/conversation_list_screen.dart
mobile/lib/screens/chat_screen.dart
mobile/lib/services/ws_client.dart (상태 노출 API)
mobile/lib/widgets/my_user_id_chip.dart (또는 설정)
N4-W3 — 인앱·브라우저 알림 대체 (Push 전)
|
|
| Status |
done (2026-08-04) |
| 목표 |
웹에서 스누즈/에스컬레이션을 OS 로컬알림 없이 인지 가능하게 |
| 비범위 |
FCM Web Push 본구현(W4), Android flutter_local_notifications 변경 |
As-is
snooze_notification_service_web.dart = no-op
- 인앱 배지/배너(C6c)는 동작 (포그라운드·리프레시 후 W1 전제)
To-be (고정 우선순위)
- 항상: 인앱 배지·배너·Inbox (기존)
- 권한 허용 시: 브라우저 Notification API로 스누즈 마감·(선택) 포그라운드 에스컬레이션 토스트성 알림
- 권한 거부/미지원: 인앱만 — 실패로 치지 않음
스케줄: 웹은 Service Worker 알람이 약하므로 포그라운드 타이머 + 다음 포커스 시 past-due 검사를 1차 경로로 한다. (백그라운드 확정 전달은 W4)
작업 분해
수락 기준
Master 액션
위험
- Safari/iOS 웹 알림 제약 → Chrome/Desktop을 데모 기준 브라우저로 명시 (W6)
예상 터치 파일
mobile/lib/services/snooze_notification_service_web.dart
mobile/lib/services/snooze_controller.dart
mobile/lib/screens/chat_screen.dart / conversation_list_screen.dart
mobile/lib/screens/settings_screen.dart (선택)
N4-W4 — Web Push (FCM)
|
|
| Status |
code shipped (2026-08-04) — live accept는 Master Firebase Web config + VAPID를 서버 .env에 넣고 web 재빌드 후 |
| 목표 |
웹 탭이 백그라운드여도 에스컬레이션 등 서버 notifyUser가 실 FCM 웹 토큰으로 전달 |
| 비범위 |
레거시 FCM_SERVER_KEY 신규 의존, 커스텀 푸시 프로토콜 |
As-is → shipped
FirebaseWebConfig + --dart-define=FIREBASE_* / FIREBASE_VAPID_KEY
PushTokenService 웹 분기: config 없으면 install: soft-fallback, 있으면 initializeApp + getToken(vapidKey:)
mobile/web/firebase-messaging-sw.js (+ Dockerfile이 template로 치환) · index.html SW 등록
- compose
web build-args · .env.example 키 이름만 · nginx no-cache for SW
Master 액션 (live accept 블로커)
- Firebase Console에 Web 앱 추가 (
msn.iykyka.com) — 프로젝트 iykyka SA와 동일 프로젝트
- Cloud Messaging Web Push 인증서/VAPID 키 발급
- 서버
~/project/ykavu/.env에 FIREBASE_API_KEY … FIREBASE_VAPID_KEY 기입 (git 금지)
docker compose up -d --build web 후 하드 리프레시 → 로그인 → /admin/push-test
작업 분해
수락 기준
위험
- SW 등록 순서/캐시로 토큰 null → 배포 후 hard refresh 절차를 W6/tester-guide에 적음
- Android
google-services.json과 Web config 혼동 → 문서에서 경로 분리
터치 파일
mobile/lib/config/firebase_web_config.dart
mobile/lib/services/push_token_service.dart
mobile/web/ (messaging SW, index 훅)
mobile/Dockerfile / docker-compose.yml / .env.example
docs/fcm-setup.md, docs/web-upgrade.md
서버
- 코어 코드 변경 없음. 기존
notifyUser / HTTP v1. 웹 토큰도 동일 messages:send
- 클라이언트 시크릿만 host
.env → compose build-args
N4-W5 — PWA
|
|
| Status |
done (2026-08-04) — W4와 독립 선행 |
| 목표 |
홈 화면 추가·standalone으로 데모 가능; 오프라인은 셸만 |
| 비범위 |
오프라인 메시지 작성/전송, 풀 오프라인 메신저 |
As-is
mobile/web/manifest.json: name/icons/display:standalone 있음
theme_color / background_color = #7C6FF0 (현 테마와 불일치)
index.html description = 플레이스홀더 (“A new Flutter project.”)
- Flutter 빌드가
flutter_service_worker.js 생성 가능 — 운영 캐시 버스트 미문서화
To-be
| 항목 |
값 |
| theme / background |
light canvas #F2F2F7 또는 accent #007AFF (택1, 구현 시 AppTheme와 맞춤) |
| description |
제품 한 줄: “나를 대신해 답하는, 나만의 와카뷰” |
| 오프라인 |
앱 셸 캐시만. API/WS는 온라인 필수 — 오프라인 시 명확한 배너(W2와 공유) |
| install |
Chrome installability (manifest + SW + HTTPS + icons) |
작업 분해
수락 기준
Master 액션
- 배포 파이프라인에 Web Firebase define이 있으면 W4와 동일 시크릿 유지
- 컷오버 후 한 번 hard refresh / “Unregister SW” 런북 숙지
위험
- SW가 오래된 main.dart.js 제공 → 배포 체크리스트에 “웹 캐시 확인” 항목
예상 터치 파일
mobile/web/manifest.json
mobile/web/index.html
deploy/nginx-web.conf (캐시 헤더, 필요 시)
docs/deploy-checklist.md / docs/tester-guide.md
N4-W6 — 테스터 운영 폴리시
|
|
| Status |
done (2026-08-04) |
| 목표 |
웹 데모 스크립트가 설치·알림·페어링·로그아웃까지 재현 가능 |
| 비범위 |
PoC 인터뷰 본실행, SHARE_URL(별도 N4-13) |
작업 분해
수락 기준
Master 액션
예상 터치 파일
docs/tester-guide.md
docs/web-upgrade.md
N4-W7 — 품질
|
|
| Status |
done (2026-08-04, edge smoke) — Playwright UI는 후속 선택 |
| 목표 |
웹 회귀를 자동화·수동 체크리스트로 고정 |
| 비범위 |
Android 에뮬레이터 UI 탭(N4-5~10), Q9 테스트 |
작업 분해
수락 기준
Master 액션
- 라이브 대상 스모크 시 DEMO 계정 충돌 주의 (display_name)
예상 터치 파일
scripts/ 또는 mobile/integration_test/
docs/web-upgrade.md 부록
2. Android N4와의 관계
| 항목 |
Android N4 |
Web N4-W |
| 서버 SA |
공유 (이미 배치된 경우 유지) |
동일 |
| 클라이언트 설정 |
google-services.json |
Firebase Web config + VAPID |
| 푸시 스모크 |
실기기 |
Chrome + /admin/push-test |
| 로컬 DB |
SQLCipher |
prefs/idb (비암호화 프리뷰) |
| 일정 |
Master 실기기 가능 시 |
문서 승인 후 웹 Wi 우선 가능 |
병행 시 서버·compose 충돌 최소화: web 이미지 빌드 args만 추가.
3. 상태 갱신 규칙
Wi를 끝낼 때마다:
- 본 문서 해당 Wi Status →
done (또는 done (부분)) + 날짜
deploy-checklist.md N4-W 표 Status 동기화
roadmap.md Web [~] 체크 갱신
- 구현 커밋과 같은 변경에 문서 체크를 넣음 (허위 done 금지)
부록 A — 웹 수동 QA 체크리스트 (구현 후)
환경: Desktop Chrome · https://msn.iykyka.com · 필요 시 시크릿 창 2개
| # |
단계 |
W 의존 |
OK |
| A1 |
새로 가입 (DEMO) + 말투 저장 |
W1 |
[ ] |
| A2 |
하드 리프레시 후 세션·말투 유지 |
W1 |
[ ] |
| A3 |
두 프로필 페어링 · 메시지 · 초안 · 뱃지 |
W2 |
[ ] |
| A4 |
WS 끊김/재연결 상태 인지 |
W2 |
[ ] |
| A5 |
스누즈 → 인앱 배지 (+ 알림 허용 시 Notification) |
W3 |
[ ] |
| A6 |
설정 → 로그아웃 → 이미 가입 로그인 |
Q8 |
[ ] |
| A7 |
실 FCM 웹 토큰 · push-test 수신 |
W4 |
[ ] |
| A8 |
PWA 설치 · standalone 시연 |
W5 |
[ ] |
| A9 |
오프라인 시 연결 필요 안내 |
W5 |
[ ] |
부록 B — Master 시크릿 체크리스트 (W4)
부록 C — 관련 문서