MMX Beta Project Documents 계획, 근거, 댓글이 같은 기록으로 남는 작업 저장소

APP_LAUNCH_AND_ROOM_SYNC_001

  • 문서 성격: 홈페이지와 Flutter 앱 사이의 방/시나리오 진입 계약 결정
  • 작성자: Codex PM
  • 결정일: 2026-05-25
  • 상태: Decision Draft

1. 배경

홈페이지에는 최소 두 종류의 진입점이 존재한다.

  • A: 시나리오 플레이 준비중인 방
  • B: 시나리오 리스트

로그인한 사용자가 A 또는 B를 클릭하면 Flutter 앱으로 넘어가야 한다.

2. 결정

A. 준비중인 방 클릭

사용자 기대 동작:

  1. 홈페이지에서 준비중인 방을 클릭한다.
  2. Flutter 앱이 열린다.
  3. 해당 방 참가 화면으로 바로 이동한다.
  4. 참가 성공 시 웹페이지와 Flutter 앱의 참가 인원이 같은 서버 상태를 기준으로 동기화된다.

기술 기준:

  • 웹과 Flutter는 같은 roomId 또는 roomCode를 사용해야 한다.
  • 참가 인원은 클라이언트가 따로 계산하지 않고 서버의 room/session participant 상태를 기준으로 표시한다.
  • Flutter 앱 진입 시 반드시 서버에 join 또는 resume 요청을 보내야 한다.
  • 웹페이지 방 목록은 같은 서버 상태를 polling 또는 realtime event로 갱신해야 한다.

B. 시나리오 리스트 클릭

사용자 기대 동작:

  1. 홈페이지에서 시나리오를 클릭한다.
  2. Flutter 앱이 열린다.
  3. 해당 시나리오의 방 만들기 화면으로 이동한다.
  4. 방 생성 시 서버에 room/session이 생성되고, 생성자가 첫 participant로 등록된다.
  5. 생성된 방은 홈페이지의 준비중인 방 목록에 반영된다.

기술 기준:

  • 웹에서 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 검증:

  1. 웹에서 준비중인 방 A를 클릭한다.
  2. Flutter가 해당 방 참가 화면으로 열린다.
  3. Flutter에서 참가하면 서버 participant count가 증가한다.
  4. 웹 방 목록의 인원이 같은 값으로 갱신된다.
  5. Flutter에서 나가거나 앱을 닫으면 서버 participant count가 감소하거나 TTL 만료 후 정리된다.

B 검증:

  1. 웹에서 시나리오 B를 클릭한다.
  2. Flutter가 해당 시나리오의 방 만들기 화면으로 열린다.
  3. 방 생성 후 생성자가 participant로 등록된다.
  4. 웹 준비중인 방 목록에 새 방이 표시된다.

7. 주의

이 항목을 놓치면 웹과 Flutter가 서로 다른 방 상태를 보게 된다. 그러면 "방은 보이는데 앱 참가자가 다르다"는 치명적인 베타 UX 문제가 생긴다.

댓글