# 1 · 랜딩

> **보는 사람**: 누구나 (로그인 전)  
> **파일**: [index.html](index.html) (화면) · [screen.js](screen.js) (이 화면 동작)

## 이 화면은

서비스 첫 화면. 세션을 만들거나(진행자) 방 코드로 들어가거나(팀원), 로그인·회원가입으로 간다.

## 누르면 어떻게 되나

| 누르는 것 | 동작 | 이동 |
|---|---|---|
| ＋ 세션 만들기 | `needLogin` | [4 세션 만들기](../04-session-create/README.md) |
| → 코드로 입장 | — | [2 방 코드 입장](../02-join-code/README.md) |
| 로그인 | — | [A1 로그인](../A1-login/README.md) |
| 회원가입 | — | [A2 회원가입 (+ 약관 팝업 A2-1 · A2-2)](../A2-signup/README.md) |
| 오른쪽 위 프로필 버튼(로그인 전) | — | [A1 로그인](../A1-login/README.md) |

## 프론트엔드

**이미 구현한 것**

- ✅ 모든 버튼 이동 연결
- ✅ "세션 만들기": 로그인 안 했으면 로그인 화면(A1)으로 → 로그인하면 세션 만들기(4)로 돌아옴
- ✅ "코드로 입장": 코드는 먼저 적게 하고, 입장 버튼을 누를 때 로그인 확인(2번 화면)
- ✅ 앱을 다시 열었을 때 로그인 유지: 저장된 토큰이 있거나, 없어도 리프레시 쿠키로 새 토큰을 받으면 로그인 상태 랜딩(1-1)으로 이동

## 백엔드가 해야 할 일 (쉽게)

- 이 화면이 서버에 하는 일은 <b>로그인 유지 확인</b> 하나예요. 브라우저에 액세스 토큰이 없으면 <code>POST /auth/refresh</code>를 불러서, 리프레시 쿠키가 살아 있으면 새 토큰을 받고 1-1로 넘어가요.
- <b>"로그인 유지" 체크</b>에 따라 리프레시 쿠키 수명이 달라요: 체크하면 30일, 안 하면 브라우저를 닫을 때까지.
- 게스트 입장은 없어요. 세션 만들기·방 입장 모두 <b>회원가입 + 로그인 + 프로필</b>이 필요해요.

## 이 화면이 쓰는 API

| 언제 | API | 요약 |
|---|---|---|
| 화면 열 때 | `POST /auth/refresh` | 로그인 유지 (액세스 토큰 새로 받기) |

## API 상세

모든 경로 앞에 `/api/v1`가 붙어요. 공통 규칙(인증·에러 형식)은 [docs/02-API-공통-규칙.md](../../docs/02-API-공통-규칙.md).

### `POST /api/v1/auth/refresh` — 로그인 유지 (액세스 토큰 새로 받기)

- **API id**: `auth.refresh` (프론트: `api.call('auth.refresh', …)`)
- **누가 부를 수 있나**: 필요 없음
- **하는 일**: 액세스 토큰이 만료됐거나 앱을 다시 열었을 때, 쿠키에 있는 리프레시 토큰으로 새 액세스 토큰을 받는다. 본문은 보내지 않는다(쿠키로 인증).

**응답** `200`

```json
{
  "user": {
    "id": "usr_001",
    "email": "hyeongwon@example.com",
    "nickname": "노형원",
    "avatarUrl": null,
    "plan": "FREE"
  },
  "accessToken": "eyJhbGciOi...",
  "expiresIn": 3600
}
```

**에러**

| code | HTTP | 언제 |
|---|---|---|
| `REFRESH_INVALID` | 401 | 리프레시 토큰이 없음 · 만료 · 로그아웃됨 · 이미 사용됨 → 다시 로그인 |

**백엔드 메모**

- 리프레시 쿠키 설정: HttpOnly · Secure · SameSite=Lax · Path=/api/v1/auth. 자바스크립트에서 읽을 수 없게.
- 회전(rotation): 쓸 때마다 새 리프레시 토큰으로 바꿔서 Set-Cookie 하고, 이전 토큰은 무효로 만든다.
- 이미 쓴(무효가 된) 리프레시 토큰이 다시 들어오면 탈취로 보고 그 사용자의 리프레시 토큰을 전부 무효화한다.
- 로그인할 때 받은 remember 값을 리프레시 토큰에 저장해 두고, 회전할 때도 같은 유지 기간을 적용한다.
- 프론트 동작: API가 401을 받으면 이 API를 한 번 부르고 성공하면 원래 요청을 다시 보낸다. 실패하면 로그인 화면으로.
