방: 나가기 버튼을 막대로 빼고 ← 홈도 나가기로, 이름 눌러 기록 카드, 게스트 경고, 관리자 계정별 기록

- 방 막대에 [🚪 나가기]를 두고 메뉴에서는 뺀다. [← 홈]도 같은 동작. 한 번 누르면 바로 나가고,
  게임 중에 자리에 앉아 있을 때만 기권 확인을 묻는다. 휴대폰은 방 링크 복사를 메뉴로 옮겨 한 줄에 맞춘다.
- 자리·관전자·결과 화면의 이름을 누르면 기록 카드(이 게임 판·승·패·무·승률, 이 방 전적, 전체 합계).
  GET /api/users/:id/stats (로그인 필요).
- 게스트 경고: 이름 정하기, 로그인 페이지, /me, 게스트가 있는 대기실.
- 관리자 사용자 상세: 전체 기록, 게임별 기록 표, 최근 게임(GET /api/admin/users/:id/games). 목록에 전적 열(PC).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-08 11:34:08 +09:00
parent f93ff4f656
commit 43156a9f63
17 changed files with 462 additions and 39 deletions

View File

@@ -42,6 +42,7 @@
- 로그아웃: 세션 삭제 + 쿠키 삭제. 게스트가 로그아웃하면 게스트 계정을 지운다(방 자리, 전적, 세션 포함, 지난 대국 기록에는 '알 수 없음'으로 남음). 확인 창에서 지워진다고 알린다.
- 게스트가 사이트를 닫고 하루(24시간) 동안 오지 않으면 같은 방식으로 지운다. 서버가 1분마다 `users.last_seen_at`(요청·소켓 종료 때 갱신)을 보고 정리하며, 소켓이 열려 있거나 방 자리를 갖고 있으면 건너뛴다.
- 계정 페이지의 "모든 기기에서 로그아웃"은 그 사용자의 모든 세션 삭제.
- 게스트로 시작하는 곳(로그인 페이지, 이름 정하기 칸), 게스트의 /me, 게스트가 있는 대기실에 "⚠️ 게스트는 기록이 오래 저장되지 않아요. 사이트에 들어오지 않은 채 하루가 지나면 계정과 기록이 모두 지워져요." 경고를 보인다.
## 6. HTTP API
| 메서드 | 경로 | 설명 |
@@ -54,6 +55,7 @@
| GET | `/api/me` | 내 정보(id, 닉네임, 종류, 아바타, 설정) |
| PATCH | `/api/me` | `{nickname?, useDiscordAvatar?, settings?}` |
| GET | `/api/me/stats` | 게임별 전적 |
| GET | `/api/users/:id/stats` | 다른 사람의 공개 정보 + 게임별 전적(방의 기록 카드, 로그인 필요) |
| DELETE | `/api/me` | 계정 삭제(확인 문구 입력 필요). 전적 익명화 |
## 7. 계정 페이지(/me)

View File

@@ -35,6 +35,8 @@
- 복사하면 버튼이 1.5초간 "복사했어요 ✓"로 바뀜 + 진동(지원 기기).
- 공유 문구: "OO님이 오목 방에 초대했어요! 코드 123 456 · https://<도메인>/r/123456"
2. **자리 목록**: 게임 인원만큼 자리 칸. 각 칸: 프로필, 닉네임, 방장 왕관, 준비 체크, 연결 상태 점(초록/노랑/회색). 빈자리는 점선 "+ 초대하기"(누르면 초대 카드로 스크롤).
- 닉네임(자리, 관전자 목록, 결과 화면)을 누르면 기록 카드가 뜬다: 이 게임의 판·승·패·무·승률, 이 방 전적, 전체 게임 합계. 패 = 판 - 승 - 무(1등이 아니면 패). 컴퓨터는 누를 수 없다. `GET /api/users/:id/stats`(로그인 필요).
- 게스트에게는 설정 카드에 "기록이 오래 저장되지 않고, 하루 동안 안 들어오면 계정과 기록이 지워진다"는 경고를 보인다(연습 방 제외).
3. **게임 설정 요약**: "오목 · 렌주룰 · 한 수 30초" + 방장에게만 [설정 바꾸기].
4. **아래 고정 버튼**(엄지 닿는 곳):
- 방장: [게임 시작] — 최소 인원이 안 되면 비활성 + "1명 더 필요해요" 안내. 모두 준비가 아니어도 시작 가능하되 "준비 안 된 사람이 있어요. 시작할까요?" 확인.
@@ -55,8 +57,9 @@
## 8. 게임 중
- 위쪽 상태 줄: 지금 할 일 문장("내 차례예요" / "OO님 차례예요"), 남은 시간 링.
- 메뉴(⋯): 규칙 보기, 소리, 글자 크기, 무르기 요청(지원 게임), 무승부 제안(지원 게임), 기권, 나가기.
- 나가기를 누르면: "게임 중에 나가면 OO 처리돼요. 정말 나갈까요?"(게임별: 2인 대전은 기권패, 카드 게임은 다이 후 자리 비움 등).
- 방 막대: [← 홈] 게임 이름 · 방 코드 링크(휴대폰은 메뉴 안) · [💬 채팅](휴대폰) · [📖 규칙](PC) · **[🚪 나가기]** · [⋯ 메뉴].
- [🚪 나가기]와 [← 홈]은 같은 동작이다: 방에서 나가고 홈으로. 한 번 누르면 바로 나가고, 게임 중에 자리에 앉아 있을 때만 "게임 중에 나가면 기권으로 처리돼요" 확인을 한 번 더 묻는다.
- 메뉴(⋯): 규칙 보기, 소리, 글자 크기, 무르기 요청(지원 게임), 무승부 제안(지원 게임), 기권. 나가기는 메뉴에 넣지 않는다.
- 관전자는 [자리 나면 참가] 대기 가능(다음 판부터).
## 9. 게임 끝
@@ -97,7 +100,7 @@ interface Room {
- 제한: 서버 전체 방 2,000개, 사용자당 동시에 만든 방 3개.
- 방 정리(1분마다): 접속이 하나도 없는 방 중 대기실은 10분, 끝난 방·멈춘 방은 30분 동안 활동이 없으면 닫는다. 컴퓨터가 있는 방(연습 방)은 마지막 사람이 나간 때부터 재서 대기실·끝난 방은 1분, 게임 중인 방은 30분 뒤 닫는다(사이트를 닫았으면 아래 규칙대로 1분). 마지막 사람이 [방 나가기]로 나가서 자리에 앉은 사람이 없으면(컴퓨터만 남았거나 아무도 들어오지 않은 방) 바로 닫는다.
- 게임 중이거나 끝난 방(대기실 제외)에서 자리에 앉은 사람이 모두 사이트를 닫으면(서버와 연결된 창이 하나도 없으면) 마지막 사람이 닫은 때부터 1분 뒤 정리 때 닫는다. 진행 중인 게임은 무효 처리되고, 관전자는 셈하지 않고, 남아 있던 관전자도 방에서 내보낸다. 대기실은 초대받은 사람이 들어올 수 있으므로 위 규칙을 따른다. 자리가 있는 사람은 다른 화면에 있어도 서버 연결을 유지한다(새로 연 창에서도 `/api/me`의 `activeRoom`이 있으면 연결).
- 방 화면을 벗어나면(홈, 규칙 등) 클라이언트가 `detach`를 보낸다. 자리는 그대로이고 '접속 중'으로 남지만, 방 메시지를 받지 않고 방의 접속 수에서도 빠진다. 그 상태로 사이트를 닫으면 연결 끊김으로 처리한다.
- [← 홈]·[🚪 나가기]가 아닌 길(사이트 로고·위쪽 '홈' 링크, 규칙, 브라우저 뒤로 가기 등)로 방 화면을 벗어나면 클라이언트가 `detach`를 보낸다. 자리는 그대로이고 '접속 중'으로 남지만, 방 메시지를 받지 않고 방의 접속 수에서도 빠진다. 그 상태로 사이트를 닫으면 연결 끊김으로 처리한다.
## 12. 컴퓨터 상대 (혼자 연습)
- 들어가는 곳: 게임 상세와 홈의 [🤖 컴퓨터와 연습하기]. 친구만 방이 열리고, 바로 시작할 수 있을 만큼 컴퓨터가 앉아 있다(예: 오목 1명, 마작 2명, 뱅 3명).

View File

@@ -62,6 +62,7 @@
- **이용 제한**: 사유와 함께 설정. 즉시 그 사용자의 모든 세션 삭제와 접속 종료. 제한된 디스코드 계정은 다시 로그인할 수 없다("이용이 제한된 계정이에요"). 해제하면 다시 로그인 가능.
- **닉네임 변경**: 관리자가 바꾸면 하루 변경 횟수 제한을 무시.
- **삭제**: `05-accounts-auth.md`의 계정 삭제와 같음(전적 익명화).
- **기록**: 목록에 사람마다 전체 판·승(PC), 상세에 전체 기록(판·승·패·무·승률), 게임별 기록 표, 최근 게임(끝난 판, 최신순 20개씩 [더 보기]: 날짜, 게임, 결과, 함께 한 사람). 연습 게임·무효 판은 판·승 수에 넣지 않지만 최근 게임 목록에는 나온다.
- **게스트 삭제 예정**: 게스트는 사이트를 나가고 하루 지나면 자동 삭제되므로(`05-accounts-auth.md` §5), 목록과 상세에 삭제 예정 시각(마지막 접속 + 24시간)을 보여 준다. 아직 사이트에 접속해 있거나 방에 자리가 있으면 "삭제 보류"로 표시한다.
- 슈퍼어드민 자신은 제한·삭제할 수 없다.
@@ -91,6 +92,7 @@ ALTER TABLE users ADD COLUMN banned_reason TEXT;
| GET | `/api/admin/audit` | 어드민+ |
| GET | `/api/admin/users?q=&page=` | 슈퍼어드민 |
| GET / PATCH / DELETE | `/api/admin/users/:id` | 슈퍼어드민 |
| GET | `/api/admin/users/:id/games?before=` | 슈퍼어드민 (최근 게임, `/api/me/games`와 같은 모양) |
| POST | `/api/admin/users/:id/logout` | 슈퍼어드민 |
| GET / POST | `/api/admin/admins` | 슈퍼어드민 |
| DELETE | `/api/admin/admins/:discordId` | 슈퍼어드민 |