APP_LAUNCH_AND_ROOM_SYNC_001
- 문서 성격: 홈페이지와 Flutter 앱 사이의 방/시나리오 진입 계약 결정
- 작성자: Codex PM
- 결정일: 2026-05-25
- 상태: Decision Draft
1. 배경
홈페이지에는 최소 두 종류의 진입점이 존재한다.
- A: 시나리오 플레이 준비중인 방
- B: 시나리오 리스트
로그인한 사용자가 A 또는 B를 클릭하면 Flutter 앱으로 넘어가야 한다.
2. 결정
A. 준비중인 방 클릭
사용자 기대 동작:
- 홈페이지에서 준비중인 방을 클릭한다.
- Flutter 앱이 열린다.
- 해당 방 참가 화면으로 바로 이동한다.
- 참가 성공 시 웹페이지와 Flutter 앱의 참가 인원이 같은 서버 상태를 기준으로 동기화된다.
기술 기준:
- 웹과 Flutter는 같은
roomId또는roomCode를 사용해야 한다. - 참가 인원은 클라이언트가 따로 계산하지 않고 서버의 room/session participant 상태를 기준으로 표시한다.
- Flutter 앱 진입 시 반드시 서버에
join또는resume요청을 보내야 한다. - 웹페이지 방 목록은 같은 서버 상태를 polling 또는 realtime event로 갱신해야 한다.
B. 시나리오 리스트 클릭
사용자 기대 동작:
- 홈페이지에서 시나리오를 클릭한다.
- Flutter 앱이 열린다.
- 해당 시나리오의 방 만들기 화면으로 이동한다.
- 방 생성 시 서버에 room/session이 생성되고, 생성자가 첫 participant로 등록된다.
- 생성된 방은 홈페이지의 준비중인 방 목록에 반영된다.
기술 기준:
- 웹에서 Flutter로
scenarioId를 전달해야 한다. - Flutter는
scenarioId를 기준으로 방 만들기 화면을 초기화한다. - 방 생성 API 응답의 room/session id가 이후 초대/참가/인원 표시의 단일 기준이 된다.
3. 필요한 인터페이스
Deep link 또는 launch URL 예시:
mmx://rooms/{roomId}/join
https://app.playmmx.com/launch/rooms/{roomId}/join
mmx://scenarios/{scenarioId}/create-room
https://app.playmmx.com/launch/scenarios/{scenarioId}/create-room
권장 payload:
{
"action": "join_room",
"roomId": "room_...",
"scenarioId": "scenario_...",
"userId": "user_...",
"returnUrl": "https://www.playmmx.com/..."
}
{
"action": "create_room",
"scenarioId": "scenario_...",
"userId": "user_...",
"returnUrl": "https://www.playmmx.com/..."
}
4. 동기화 원칙
참가 인원 동기화는 아래 원칙을 따른다.
- 서버가 단일 source of truth다.
- 웹과 Flutter는 모두 서버의 participant count를 읽는다.
- Flutter 앱 진입 시 optimistic count를 임의로 올리지 않는다.
- join/resume/leave/close는 모두 서버 이벤트 또는 polling으로 웹에 반영한다.
- 앱 종료/탭 닫기 leave는 best-effort이며, 완전한 정합성은 heartbeat/TTL presence로 보강한다.
5. M0/M1/M2 배치
M0:
- Flutter Web/로컬 앱 기준 launch URL 파라미터를 받아 특정 방 참가 또는 방 만들기 화면으로 이동하는 최소 라우팅.
- 서버 room participant count를 양쪽에서 동일하게 읽는지 수동 검증.
M1:
- Android/Windows Flutter 앱 deep link 정리.
- 시나리오 상세/방 생성 화면의 UX 보강.
M2:
- 로그인 계정 기반 user/session token 연동.
- heartbeat/TTL presence로 앱 강제 종료, 네트워크 단절, 중복 접속 정합성 보강.
6. 검증 기준
A 검증:
- 웹에서 준비중인 방 A를 클릭한다.
- Flutter가 해당 방 참가 화면으로 열린다.
- Flutter에서 참가하면 서버 participant count가 증가한다.
- 웹 방 목록의 인원이 같은 값으로 갱신된다.
- Flutter에서 나가거나 앱을 닫으면 서버 participant count가 감소하거나 TTL 만료 후 정리된다.
B 검증:
- 웹에서 시나리오 B를 클릭한다.
- Flutter가 해당 시나리오의 방 만들기 화면으로 열린다.
- 방 생성 후 생성자가 participant로 등록된다.
- 웹 준비중인 방 목록에 새 방이 표시된다.
7. 주의
이 항목을 놓치면 웹과 Flutter가 서로 다른 방 상태를 보게 된다. 그러면 "방은 보이는데 앱 참가자가 다르다"는 치명적인 베타 UX 문제가 생긴다.